Страница 1 из 1

Абстрактный класс.

Добавлено: 07 ноя 2010, 22:59
Евгений Александрович
Есть базовый абстракт. класс base. От него 2 производных first and second.
Проблемы:
1) Почему не могу вызвать метод WeightSort() вот так: p->WeightSort(); (см. main(){ ...} .)
2) Нужно: Реализовать методы вывода на экран информации, содержащейся в производных классах по указателю на базовый класс. ( Я так понимаю это я и сделал (см. main(){...}. ) Все указатели, используемые в программе должны быть реализованы в виде "умных" указателей( для "умных" указателей использовать шаблонный класс.
( Как вообще подойти к этому устовию? Нужно какой-то отдельный класс? но что в нем должно быть?)

Код: Выделить всё

class base
{
public:
	int n;
	base(){n=0;}
	virtual ~base(){}
	virtual void AddDate()=0;
	virtual void print()=0;
    virtual void WeightSort(); 
};
class first :p ublic base
{
public:
	first(){naznachenie=NULL; weight=NULL;}
	virtual ~first();
	void AddDate();
	void print()
	{
		for(int i=0;i<n;i++)
		cout<<"naznachenie: "<<naznachenie[i]<<"; weight: "<<weight[i]<<endl;
	}
	void WeightSort(); 
private:
	char **naznachenie;
	int *weight;
};
class second :p ublic base
{
public:
	second(){adress=NULL;}
	virtual ~second();
	 void AddDate();
	void print(){
		for(int i=0;i<n;i++)
			cout<<"name: "<<name[i]<<"; adress:"<<adress[i]<<endl;}
private:
	char **name;
	char **adress;
};

...
...
.... // реализация методов AddDate() для обоих произв. классов

void first::WeightSort()
{
	int b;
	for(int j=1;j<n;j++)
		for(int i=0;i<n-j;i++)
			if(weight[i]>weight[i+1])
			{
				b=weight[i];
				weight[i]=weight[i+1];
				weight[i+1]=b;
			}
			for(int i=0;i<n;i++)
			{
				if(weight[i]<1000) cout<<"(<50)__it`s a letter!"<<endl;
				else cout<<"__it`s a banderol or send"<<endl;
			}
			system("pause");
}

...
...
... // реализация деструкторов

void main()
{
	base *p;
       first fst;
	   second snd;

	   p=&fst;
	   p->AddDate();
	   p->WeightSort();    [B]Error![/B]
                         p->print();
  
	   p = &snd;
	   p->AddDate();
	   p->print();

	   system("PAUSE");
}

Re: Абстрактный класс.

Добавлено: 08 ноя 2010, 11:03
BBB
Может, все-таки, в описании функций AddDate, print, WeightSort в класах-наследниках дописать virtual?
(не укаазли, что за ошибка выдается на p->WeightSort())

Re: Абстрактный класс.

Добавлено: 08 ноя 2010, 19:13
Евгений Александрович
Ошибка:
fatal error LNK1120: 1 неразрешенных внешних элементов
Дописывал vitrual , но все равно это-же ошибка.

Re: Абстрактный класс.

Добавлено: 09 ноя 2010, 10:00
Albor
base::WeightSort() не чисто виртуальная - должно быть тело.

Re: Абстрактный класс.

Добавлено: 10 ноя 2010, 01:48
Евгений Александрович
Albor, спасибо, все заработало.

Но мне еще нужно:
Реализовать методы вывода на экран информации, содержащейся в производных классах по указателю на базовый класс. Все указатели, используемые в программе должны быть реализованы в виде "умных" указателей( для "умных" указателей использовать шаблонный класс).

- Я так понимаю нужно создать как-то новый cpp проект(который подключить, затем, к основному) , где будет реализация smart pinter(a) . Непонятно: как правильно завернуть в шаблон мою попытку реалтзовать умный указатель.(я так думаю не правильно в шаблон завернул) и как через этот "умный" указатель в main() обращаться к методам моих классов? (т.е.как вообще можно связать мой указатель и мои классы )

Код: Выделить всё

template <class T>
class A
{
private:
	int count;
public:
	A(){ count =0;}
	void add(){ count ++;}
	void del(){ if(--count==NULL) delete this;}
};
template <class T>
class Aptr
{
private:
	T *aptr;
public:
	Aptr(A *p) { aptr=p; p->add();}
	~Aptr(){ aptr->del();}
	T * operator ->() {return aptr;}
};

Re: Абстрактный класс.

Добавлено: 10 ноя 2010, 12:30
BulldozerBSG
Реализацию умных указателей можно подсмотреть в библиотеке boost

Re: Абстрактный класс.

Добавлено: 10 ноя 2010, 20:55
Евгений Александрович
Реализацию умных указателей можно подсмотреть в библиотеке boost
Это мне нельзя еще использовать. Да и не знаю как пока.

В данной реализации указателя, класс А - для подсчета ссылок, а класс Aptr - сам указатель. Aptr зависит от А. Я хочу применить эту систему(Aptr и А ) к какому-либо методу из класса , допостим класса base. Как это сделать?

Код: Выделить всё

class A
{
private:
	int count;
public:
	A(){ count =0;}
	void add(){ count ++;}
	void del(){ if(--count==NULL) delete this;}
};
class Aptr
{
private:
	A *aptr;
public:
	Aptr(A *p) { aptr=p; p->add();}
	~Aptr(){ aptr->del();}
	A * operator ->() {return aptr;}
};


class base
{
public: void fun();
};

Re: Абстрактный класс.

Добавлено: 12 ноя 2010, 11:31
Romeo
Я в своё время делал так:

- Стуктура SInternalData содержит указатель на класс А, который нужно рефкаунтить и дополнительно ещё одно поле long - счётчик ссылок.
- Стуктура SInternalData имеет метод AddRef, увеличивающий счётчик и метод Relese, уменьшающий счётчик и вызывающий delete this, если счёчик равен нулю.
- Класс CSmartPtr содержит внутри себя указатель на структуру SInternalData.
- Класс CSmartPtr не имеет дефолтного конструктора.
- Класс CSmartPtr имеет конструктор, принимающий указатель на A. В теле конструктора создаётся новый SInternalData со счёткиком ссылок = 1 и в неё прописывается пришедший снаружи указатель на A.
- Класс CSmartPtr в констукторе копирования переприсваивает указатель на SInternalData у копируемого объекта и увеличивает счёткик ссылок внутри него.
- В операторе присваивания класса CSmartPtr делается проверка на this, чтобы не копировать в себя, затем вызывается Release для SInternalData, переприсваивается указатель из внешнего SInternalData и у него делается AddRef.
- В деструкторе CSmartPtr вызывает Release для внутреннего указателя на SInternalData.

Пробуй реализовать, если не получится - будем помогать. Ещё я не сказал, что класс А у меня был шаблонным параметром, но ты сделай пока хотя бы без шаблонов.