G++ 忽略覆盖的虚函数
g++ ignores overwritten virtual function
我有两个这样的类(简化和重命名(:
class Base
{
public:
virtual void operator()( ) { cout << "Basen";}
};
class Derived : public Base
{
public:
void operator()( ) { cout << "Derivedn"; }
};
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;
}
当我运行这个时,我得到:
Base
Base
Base
即调用 Base::operator((。显然这不是我想要发生的事情。我尝试将doSomething更改为
void doSomething( Base& obj )
但这仅在直接使用 Derived 对象而不是列表中的对象调用时才有效。并且引用不能存储在列表中。
有什么方法可以让doSomething"看到"它必须调用派生类的函数(而不必求助于指针(?
编辑:指出问题,对于可能遇到此问题的其他人,这里有一个链接:什么是对象切片?
以下内容:
list<Base> bList;
Derived d1, d2, d3;
bList.push_back( d1 );
bList.push_back( d2 );
bList.push_back( d3 );
对对象进行切片。它们不再是Derived
型,而是Base
型。您需要在容器中使用指针或智能指针来实现预期行为。
阅读对象切片。
问题不在于编译器没有"看到"它需要在派生类中调用函数,问题在于您只将基类存储在容器list<Base>
中。这导致了通常所说的对象切片。当编译器将Derived
对象复制到只能容纳Base
对象的容器中时,它只能复制对象的基部分并"切片"使其成为Derived
对象的部分。
为了对遵循值语义的容器使用多态性(即,假设您将实际对象存储在其中,而不是对对象的引用形式(,您需要存储指向所述对象的指针。我建议不要将原始指针存储在标准库容器中,因为它引入了额外的生命周期管理问题 - 您必须从容器外部控制指向对象的生存期,这往往是一个非常糟糕的主意,通常会导致内存泄漏或悬空指针,如果不是两者兼而有之。
我的建议是,如果您可以使用 boost,请使用为此目的显式设计的ptr_container
模板类之一。如果您不能,并且您使用的是足够现代的编译器,则可以使用std::list<std::shared_ptr<Base> > >
并依靠shared_ptr
来管理对象的生命周期。
上面的答案引导我找到最终的解决方案。 简短的回答是:"不。 您必须使用指针列表。 这是我想出的...
#include <iostream>
#include <memory>
#include <list>
class Base
{
public:
virtual void foo()
{
std::cout << "Base::foo" << std::endl;
}
};
class Derived : public Base
{
public:
void foo()
{
std::cout << "Derived::foo" << std::endl;
Base::foo();
}
};
int main()
{
std::list<std::shared_ptr<Base>> bases;
auto p = std::make_shared<Derived>();
bases.push_back(p);
for (std::list<std::shared_ptr<Base>>::iterator i = bases.begin(); i != bases.end(); i++)
{
(*i)->foo();
}
return 0;
}
- 使用可变参数函数覆盖具有不同函数签名的虚函数
- 如何使用用户定义的函数覆盖 C lib 函数,如 _sbrk?
- 函数覆盖有哪些用例?
- 在子类函数覆盖中省略具有默认值的参数
- C++ 成员变量被非成员函数覆盖
- 用现有函数覆盖虚拟函数
- 函数覆盖是否由编译器自动完成
- 结构被库函数覆盖
- 当在Python中定义__str__时,如何将C 的标准全局函数覆盖
- C++类是否解决函数覆盖问题
- 用私有基函数覆盖公共虚拟函数
- 优先级队列中复制构造函数覆盖的值
- 虚拟函数覆盖预期错误
- C++中的函数覆盖无需"虚拟"即可工作
- C++虚拟函数覆盖
- 如何用非虚拟函数覆盖虚拟函数
- 基成员函数的所有重载是否可以被单个模板化成员函数覆盖和转发到
- C++继承函数覆盖
- 纯虚函数覆盖虚函数
- 引用项目的Qt-main()函数覆盖实际项目的main()