【发布时间】:2020-10-09 12:22:39
【问题描述】:
我遇到了一个旧的SO post about inheriting from std::vector。我不清楚其中一个 cmets,为什么当您从标准库容器继承并使用指向基的指针/引用时会发生切片?
#include <vector>
#include <iostream>
using namespace std;
class MyVec : public vector<int>
{};
void printTypeBase(vector<int>& vecObj)
{
cout << "base parameter ref: " << typeid(vecObj).name() << endl;
}
void printTypeDerived(MyVec& vecObj)
{
cout << "derived parameter ref: " << typeid(vecObj).name() << endl;
}
int main()
{
auto myVec = MyVec{};
printTypeBase(myVec);
printTypeDerived(myVec);
}
输出:
基本参数参考:St6vectorIiSaIiEE
派生参数参考:5MyVec
当我尝试在 printTypeBase 内进行动态转换时:
auto temp = dynamic_cast<MyVec&>(vecObj);
我收到一条明确的错误消息:
错误:'std::vector
' 不是多态的
回想起来,我的问题应该是为什么std::vector 不是多态类型?
【问题讨论】:
-
这里没有进行切片,因为使用了指向引用的指针。在任何地方用
class foo替换std::vector<int>,你会得到相同的结果。 -
C++ 中的类型不是动态的,它们是固定的和静态的。在
printTypeBase函数中,vecObj变量是对vector<int>的引用,编译器无法更改它。 -
这不是切片。
MyVec是一个空的派生类。里面没有什么可以切的。如果要查看切片,则添加一个数据成员,例如int,然后通过vector<int>&复制对象。然后你得到int成员的切片,因为vector<int>::operator=对int成员一无所知。 -
@SamVarshavchik when I replace vector<int> with a foo class 其中包含虚函数,我得到“正确”行为,typeid 为这两个函数打印“MyVec”。我现在明白了关于非多态类型的意义,所以这是有道理的。
-
即使使用虚函数,仍然不会发生切片。它仅在基类被复制 时发生。不进行复制。
typeid并不表示对象切片正在发生。
标签: c++ inheritance containers