我有两个类,其中一个继承另一个:
class baseClass
{
public:
virtual void show();
};
void baseClass::show(){cout << "Base class" << endl;}
class derivedClass
{
public:
void show();
};
void derivedClass::show(){cout << "Derived class" << endl;}
如果我创建一个derivedClass对象并调用show函数,它会正确打印“Derived class”。如果我执行以下操作:
derivedClass b;
baseClass* b;
b=&d;
b->show();
它再次正确打印出“派生类”。 但是,如果我这样列出一个列表:
list<baseClass> t;
list<baseClass>::iterator it;
baseClass b;
derivedClass d;
t.push_back(b);
t.push_back(d);
并尝试在每个项目上调用show:
it = t.begin();
it->show();
it++;
it->show();
b和d的输出都是“基类”。 我的问题是:为什么它只使用show()的baseClass版本,如何才能正确使用派生版本的列表中的derivedClass对象?
提前致谢
答案 0 :(得分:1)
您必须将方法show()
声明为virtual
以使多态性有效:
class baseClass
{
public:
virtual void show();
};
void baseClass::show(){cout << "Base class" << endl;}
class derivedClass : public baseClass
{
public:
virtual void show();
};
void derivedClass::show(){cout << "Derived class" << endl;}
你也失踪了class derivedClass : public baseClass
。
最后的问题。你需要使用指针。
list<baseClass*> t;
list<baseClass*>::iterator it;
baseClass b;
derivedClass d;
t.push_back(&b);
t.push_back(&d);
并改为:
it = t.begin();
(*it)->show();
it++;
(*it)->show();
答案 1 :(得分:0)
它再次正确打印出“派生类”。但是,如果我这样列出一个列表:
没有。它无法打印“派生类”。事实上,这一行:
b=&d;
将提供compilation error,因为b
不是d
的多态基础。
在基类中将show
声明为virtual
:
virtual void show();
然后那将编译。
但是,即使将show
虚拟推送到派生类的对象,也会导致对象切片,因为列表只能包含基类对象;这意味着,列表将获得派生类对象的子对象。这是因为您已将列表声明为:
list<baseClass> t;
这是不正确的。
声明为:
list<baseClass*> t;
并推送pointer
反对这一点,如下所示:
derivedClass d;
derivedClass *pd = new derivedClass;
baseClass b;
t.push_back(&d);
t.push_back(pd); //note there is no `&`
t.push_back(&b);
//use t
//must delete pd
delete pd;
-
请注意,如果要删除派生类的对象,请使用类型为基类的指针,如下所示:
baseClass *bptr = new derivedClass();
delete bptr;
然后你要将baseClass
的析构函数定义为虚拟,否则上面的delete语句将调用未定义的行为。
这样做:
class baseClass:
{
//...
virtual ~baseClass();
};