我有两个这样的类(简化和重命名):
class Base
{
public:
virtual void operator()( ) { cout << "Base\n";}
};
class Derived : public Base
{
public:
void operator()( ) { cout << "Derived\n"; }
};
void doSomething( Base obj )
{
obj( );
}
int main( )
{
list<Base> bList;
Derived d1, d2, d3;
bList.push_back( d1 );
bList.push_back( d2 );
bList.push_back( d3 );
for( list<Base>::iterator it = bList.begin(); it != bList.end(); it++ )
{
doSomething( *it );
}
return 0;
}
Run Code Online (Sandbox Code Playgroud)
当我运行这个时,我得到:
Base
Base
Base
Run Code Online (Sandbox Code Playgroud)
即调用Base :: operator().显然这不是我想要发生的事情.我尝试将doSomething更改为
void doSomething( Base& obj )
Run Code Online (Sandbox Code Playgroud)
但这仅在使用Derived对象直接调用而不是从列表中调用时才有效.并且引用不能存储在列表中.
有什么方法可以让doSomething"看到"它必须调用派生类的函数(不必求助于指针)?
编辑:指出了问题,对于其他可能遇到此问题的人是一个链接: 什么是对象切片?
下列:
list<Base> bList;
Derived d1, d2, d3;
bList.push_back( d1 );
bList.push_back( d2 );
bList.push_back( d3 );
Run Code Online (Sandbox Code Playgroud)
切片你的对象.它们不再是类型Derived,而是Base.您需要在容器中使用指针或智能指针来实现预期的行为.
阅读对象切片.