C++ 在基类向量上调用虚函数

C++ 在基类向量上调用虚函数,c++,virtual,C++,Virtual,我创建了一些代码来重现问题: #包括“stdafx.h” #包括 #包括 甲级 { 受保护的: int m_X; 公众: A(){ std::cout快速修复方法是将As类更改为以下内容: class As { public: void AddA( A &a ){ m_As.push_back( &a ); } void PrintXs() { for ( auto a : m_As ) { a-&g

我创建了一些代码来重现问题:

#包括“stdafx.h”
#包括
#包括
甲级
{
受保护的:
int m_X;
公众:
A(){

std::cout快速修复方法是将
As
类更改为以下内容:

class As
{
public:
    void AddA( A &a ){ m_As.push_back( &a ); }
    void PrintXs()
    {
        for ( auto a : m_As )
        {
            a->printX();
        }
    }
private:
    std::vector<A*> m_As;
};
类作为
{
公众:
void AddA(A&A){m_As.push_back(&A)}
void PrintXs()
{
用于(自动a:m_As)
{
a->printX();
}
}
私人:
std::向量m_-As;
};

当您使用
std::vector m_As;
时,向量只能适合
A
对象。如果您使用指针,则多态性可以工作并调用正确的
printX
函数。但是,如果指向对象的生存期到期,则存在指针悬空的问题。要处理此问题,最好使用smart指针类,如
std::unique\u ptr

由于您是按值传递对象,因此无法利用多态性。请通过(智能)指针或引用传递它们

 std::vector<std::shared_ptr<A>> m_As;

 // or 

 std::vector<std::unique_ptr<A>> m_As;

 // or 

 std::vector<A*> m_As; // be careful of bare pointers

 // or (since C++11)

 std::vector<std::reference_wrapper<A>> m_As;
使用最后一个代码,您不必更改
main
code


您所做的是调用。这是您获取派生类的对象并修剪掉不在父类中的所有内容,然后将其分配给父类

你要做的就是按照你解释的去做。要做到这一点,把你的向量从对象的副本改为对象的ptr

如果对更多细节感兴趣,请使用提供的链接,其中包含的信息似乎非常完整

for ( const auto & a : m_As )
{
        a.printX();
}

它将阻止您扩展副本,并提供B实例而不是A实例,以副本的形式出现。

多态性需要指针或引用!在
m_as.push_back(A);
,由
A
引用的对象将被复制到新的
A
对象中。(我有一个答案包含了这一点,并删除了它,因为需要指针,杰西在这一点上击败了我。)@cdhowie:当然,我更新了我的答案,并用基于引用的
std::reference\u wrapper
编写了一个示例。
for ( const auto & a : m_As )
{
        a.printX();
}