多态对象列表

list of polymorphic objects

本文关键字:列表 对象 多态      更新时间:2023-10-16

下面有一个特定的场景。下面的代码应该打印B和C类的"say()"函数,并打印"B says.."C说…"但事实并非如此。任何想法。。我正在学习多态性,所以在下面的代码行中也评论了一些与之相关的问题。

class A
{
public:
// A() {}
    virtual void say() { std::cout << "Said IT ! " << std::endl; }
    virtual ~A(); //why virtual destructor ?
};
void methodCall() // does it matters if the inherited class from A is in this method
{
    class B : public A{
    public:
        // virtual ~B(); //significance of virtual destructor in 'child' class
        virtual void say () { // does the overrided method also has to be have the keyword  'virtual'
            cout << "B Sayssss.... " << endl; 
        }
    };
    class C : public A {
    public:
        //virtual ~C();
        virtual void say () { cout << "C Says " << endl; }
    };
    list<A> listOfAs;
    list<A>::iterator it;
    # 1st scenario
    B bObj; 
    C cObj;
    A *aB = &bObj;
    A *aC = &cObj;
    # 2nd scenario
    //  A aA;
    //  B *Ba = &aA;
    //  C *Ca = &aA; // I am declaring the objects as in 1st scenario but how about 2nd   scenario, is this suppose to work too?
    listOfAs.insert(it,*aB);
    listOfAs.insert(it,*aC);
    for (it=listOfAs.begin(); it!=listOfAs.end(); it++)
    {
        cout <<  *it.say()  << endl;
    }
}
int main()
{
    methodCall();
    return 0;
}

您的问题被称为切片,您应该检查这个问题:学习C++:多态性和切片

您应该将此列表声明为指向AS:的指针列表

list<A*> listOfAs;

然后插入这些指向它的aBaC指针,而不是创建它们所指向的对象的副本。将元素插入列表的方式是错误的,您应该使用push_back函数来插入:

B bObj; 
C cObj;
A *aB = &bObj;
A *aC = &cObj;
listOfAs.push_back(aB);
listOfAs.push_back(aC);

然后你的循环可能看起来像这样:

list<A*>::iterator it;
for (it = listOfAs.begin(); it != listOfAs.end(); it++)
{
    (*it)->say();
}

输出:

B Sayssss....
C Says

希望这能有所帮助。

虚拟类层次结构的多态性仅通过引用指向基本子对象的指针起作用:

struct Der : Base { /* ... */ };
Der x;
Base & a = x;
a.foo();   // calls Der::foo() from x

如果函数CCD_ 5是CCD_;多态性是指当您调用类型为Base的对象的成员函数时,实际被调用的函数可能在类Der中实现。

容器只能存储固定类型的元素。为了存储多态集合,您可以使用一个指向基类的指针容器。由于您需要将实际对象存储在其他地方,因此生命周期管理是不平凡的,最好留给专用包装器,如unique_ptr:

#include <list>
#include <memory>

int main()
{
    std::list<std::unique_ptr<Base>> mylist;
    mylist.emplace_back(new Der1);
    mylist.emplace_back(new Der2);
    // ...
    for (p : mylist) { p->foo(); /* dispatched dynamically */ }
}

list::iterator it; B bObj; C cObj; A *aB = &bObj; A *aC = &cObj; listOfAs.insert(it,*aB);

你不需要初始化"it"吗?我认为你应该这样做=listOfAs.begin();在开始插入之前。