使用列表对象内的对象的派生函数

时间:2011-09-18 03:12:08

标签: c++ list inheritance polymorphism derived

我有两个类,其中一个继承另一个:

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对象?

提前致谢

2 个答案:

答案 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();
};