[英]Calling a virtual function of the base class in a non virtual function of the base class
[英]Calling a virtual function on a vector of base classes
我创建了一些代码来重现问题:
#include "stdafx.h"
#include <iostream>
#include <vector>
class A
{
protected:
int m_X;
public:
A() {
std::cout << "in A ctor" << std::endl;
m_X = 0;
}
virtual void printX(){ std::cout << "in A " << m_X << std::endl; }
};
class B : public A
{
public:
B() {
std::cout << "in B ctor" << std::endl;
m_X = 1;
}
virtual void printX(){ std::cout << "in B " << m_X << std::endl; }
};
class As
{
public:
void AddA( const A &a ){ m_As.push_back( a ); }
void PrintXs()
{
for ( auto a : m_As )
{
a.printX();
}
}
private:
std::vector<A> m_As;
};
int _tmain(int argc, _TCHAR* argv[])
{
As as;
B b;
as.AddA( b );
as.PrintXs();
system("pause");
return 0;
}
这个的输出是:
在演员
在 B ctor
在 A 1
我想要“在 B 1”而不是“在 A 1”。 我确信我对虚拟的理解是有缺陷的。 我必须如何更改代码以调用 B PrintX()? 请注意,会有其他类从 A 继承,所以我真的不想编写静态调用。
谢谢。
快速修复是将您的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;
};
当你使用std::vector<A> m_As;
,向量只能适合A
对象。 如果您改用指针,则多态可以工作并调用正确的printX
函数。 但是,如果指向的对象的生命周期到期,则会出现悬空指针的问题。 为了解决这个问题,最好使用像std::unique_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;
对于最后一个,您可以使用std::reference_wrapper
和std::ref
:
class As
{
public:
void AddA(A &a){ m_As.push_back( std::ref(a) ); }
void PrintXs() const
{
for ( auto a : m_As )
{
a.get().printX();
}
}
private:
std::vector<std::reference_wrapper<A>> m_As;
};
使用最后的代码,您不必更改main
代码。
for ( const auto & a : m_As )
{
a.printX();
}
它会让你远离扩展副本并提供 B 实例而不是 A 实例,作为副本出现。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.