Страницы

Поиск по вопросам

четверг, 11 июля 2019 г.

Абстрактный класс для копирования объекта и указатель для него

т.к. базовый класс - абстрактный, то для создания объекта используем указатель и void show() { cout << ptr[i] } выводит адрес элемента, а не его значение. При попытке вывести на экран *ptr[i] естественно возникает ошибка:
Invalid operands to binary expression ('ostream'(aka 'basic_ostream') and 'Obj')
как можно привести типы?
#include #include
using namespace std;
class Obj { public: virtual Obj* clone() = 0; };
class IntObj : public Obj { int element; public: IntObj(){}; IntObj (int temp) { element = temp; } Obj* clone() { return new IntObj(element); } };
class DoubleObj : public Obj { double element; public: DoubleObj(){}; DoubleObj (double temp) { element = temp; } Obj* clone() { return new DoubleObj(element); } };
class StringObj : public Obj { string element; public: StringObj(){}; StringObj (string temp) { element = temp; } Obj* clone() { return new StringObj(element); } };
class Stack { Obj **ptr; int size = 1; public: Stack() { ptr = new Obj*[size]; }
Stack(const Stack &s) { size = s.getSize(); for(int i = 0; i < size; i++) *ptr[i] = s.getPtr()[i]; }
~Stack() { delete [] ptr; }
Obj *getPtr() const { return *ptr; } int getSize() const { return size; }
void push(Obj *obj) { Obj** ptrTemp = new Obj*[size];
ptr[size - 1] = obj->clone();
for (int i = 0; i < size; i++) ptrTemp[i] = ptr[i];
delete [] ptr;
size++;
ptr = new Obj*[size];
for (int i = 0; i < size - 1; i++) ptr[i] = ptrTemp[i];
delete [] ptrTemp; }
void del () { Obj** ptrTemp = new Obj*[size];
for (int i = 0; i < size - 1; i++) ptrTemp[i] = ptr[i];
delete [] ptr;
size--;
ptr = new Obj*[size];
for (int i = 0; i < size - 1; i++) ptr[i] = ptrTemp[i];
delete [] ptrTemp; }
Obj* pop() { if (size > 1) { Obj *temp; temp = ptr[size - 2]; del(); return temp; } else { cout << "Стек был пуст.
"; delete [] ptr; exit(EXIT_FAILURE); } }
void show() { if (size > 1) { cout << "Печать стека: ";
for (int i = size - 1; i >= 0; i--) cout << ptr[i] << " ";
cout << "
"; } else cout << "Стек пуст.
"; } };
int main() { Stack i; Obj *ai = new IntObj(5); IntObj *bi = dynamic_cast(ai); i.push(bi); i.show();
Stack d; Obj *ad = new DoubleObj(5.0); DoubleObj *bd = dynamic_cast(ad); d.push(bd); d.show();
Stack s; Obj *as = new StringObj("aaa"); StringObj *bs = dynamic_cast(as); s.push(bs); s.show();
return 0; }


Ответ

Вы можете объявить виртуальные функции в производных классах следующим образом
IntObj* clone() { return new IntObj(element); } DoubleObj* clone() { return new DoubleObj(element); } StringObj* clone() { return new StringObj(element); }
И тогда проблем у вас не будет, если вы еще объявите виртуальными те функции, которые собираетесь вызывать для каждого созданного объекта.
Вот вам демонстрационная программа, которую вы можете использовать в качестве образца для реализации вашей программы
#include #include
class Obj { public: virtual Obj* clone() const = 0; virtual std::ostream & out( std::ostream & ) const = 0; virtual ~Obj() {} };
class IntObj : public Obj { int element; public: IntObj(){}; IntObj (int temp) { element = temp; } IntObj* clone() const { return new IntObj(element); } std::ostream & out( std::ostream &os ) const { return os << element; } };
class DoubleObj : public Obj { double element; public: DoubleObj(){}; DoubleObj (double temp) { element = temp; } DoubleObj* clone() const { return new DoubleObj(element); } std::ostream & out( std::ostream &os ) const { return os << element; } };
class StringObj : public Obj { std::string element; public: StringObj(){}; StringObj ( const std::string &temp ) { element = temp; } StringObj* clone() const { return new StringObj(element); } std::ostream & out( std::ostream &os ) const { return os << element; } };
std::ostream & operator <<( std::ostream &os, const Obj &obj ) { return obj.out( os ); }
int main() { Obj * a[3];
a[0] = IntObj( 10 ).clone(); a[1] = DoubleObj( 10 ).clone(); a[2] = StringObj( "10" ).clone();
for ( Obj *p : a ) std::cout << *p << std::endl;
delete [] a;
return 0; }
Ее вывод на консоль:
10 10 10
Все, что вам остается, это корректно реализовать свой стек.

Комментариев нет:

Отправить комментарий