vector.push_back(B) and vector.push_back(new A((*B))), why not act as the same?
我有这两门课:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 | class A { public: A(); virtual ~A(); virtual void TellMyName(); }; class B : public A { private: std::string szName; public: B(); ~B(); void TellMyName(); void SetName(std::string val){ szName = val; } }; |
这是我的代码:
1 2 3 4 5 6 7 8 9 10 11 12 13 | void main() { std::vector<A*> List_A; B* B_Instance = new B(); B_Instance->SetName("B"); List_A.push_back(B_Instance); // Way 1 List_A.push_back(new A((*B_Instance))); // Way 2 List_A[0]->TellMyName(); List_A[1]->TellMyName(); } |
1 | List_A.push_back(new A((*B_Instance))); // Way 2 |
这条线并没有做你认为的事情。
通过调用C++生成的默认复制构造函数,您正在堆上创建类"A"的新实例。该复制构造函数使用B的实例(视为A的实例)并逐字段复制,在本例中,该实例不起任何作用。
您实际上是在创建的空实例并将其推到列表中。
正如许多人所提到的,这个正式术语称为对象切片。
你应该打电话来
1 | List_A.push_back(new B((*B_Instance))); |
由于
调用
1 2 3 | std::vector<A*> List_A; // ... List_A.push_back(new A((*B_Instance))); // Way 2 |
你正在遭受一种物体切片的痛苦,有点。
对象切片发生在用派生类型的值实例化(或分配)一个基类,并丢失(或"切片")派生类唯一的所有内容时。
上面,您正在实例化一个
1 | List_A.push_back(new B(*B_Instance)); // Way 2 |
尽管如此,我还是强烈建议您考虑重构代码以使用智能指针。
that means all members of the B class are empty like they're never being filled with anything
不,这并不意味着它们是空的。要想空无一人,首先他们必须在那里。
你碰到了切片问题。