т.к. базовый класс - абстрактный, то для создания объекта используем указатель и void show() { cout << ptr[i] } выводит адрес элемента, а не его значение. При попытке вывести на экран *ptr[i] естественно возникает ошибка:
Invalid operands to binary expression ('ostream'(aka 'basic_ostream') and 'Obj')
как можно привести типы?
#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
Stack d;
Obj *ad = new DoubleObj(5.0);
DoubleObj *bd = dynamic_cast
Stack s;
Obj *as = new StringObj("aaa");
StringObj *bs = dynamic_cast
return 0;
}
Ответ
Вы можете объявить виртуальные функции в производных классах следующим образом
IntObj* clone() { return new IntObj(element); }
DoubleObj* clone() { return new DoubleObj(element); }
StringObj* clone() { return new StringObj(element); }
И тогда проблем у вас не будет, если вы еще объявите виртуальными те функции, которые собираетесь вызывать для каждого созданного объекта.
Вот вам демонстрационная программа, которую вы можете использовать в качестве образца для реализации вашей программы
#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
Все, что вам остается, это корректно реализовать свой стек.
Комментариев нет:
Отправить комментарий