Calling subclass methods from superclass in a vector C++
我试图在一个向量中添加一些子类元素,遍历它们调用一个被重写的方法,并希望它在可能的情况下调用被重写的方法。然而,我发现它似乎只是在调用超类方法。
我学习了Java,我不确定为什么它在C++中这样做。我尝试使用超类指针的向量重写代码,并将子类的指针强制转换为超类。然后通过指针访问这个。
理想情况下,我不想在向量中放置指针列表,因为我必须手动删除每个指针(我相信?)为了防止内存泄漏,因为我将使用new创建对象,以便它们在方法调用之后保持不变,以便将它们添加到向量中。
有没有更好的方法可以做到这一点,或者当父类不需要时,我坚持使用指针并对创建的对象调用delete?向量最好是类X的列表,而不是类X的指针列表。
我的结构是:
1 2 3 4 5 | class a { vector vec of class X, method to create and add an instance of X into vector vec, method to create and add an instance of Y into vector vec } class X { talk() } class Y : public X { talk() } |
代码来演示我理想中想要做的事情,但只通过调用超类方法来显示它的中断:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 | #include <stdio.h> #include <stdlib.h> #include <iostream> #include <vector> class A { public: virtual void talk() { printf("A "); } }; class B: public A { public: void talk() { printf("B "); } }; int main(void) { std::vector<A> vec; std::vector<A*> vec2; A a; B b; a.talk(); b.talk(); vec.push_back(a); vec.push_back(b); vec2.push_back(&a); vec2.push_back(&b); for(int i = 0; i < vec.size(); i++) { vec[i].talk(); vec2[i]->talk(); //bad but short for example } } |
型
要获得所需的多态行为,需要向要在派生类中重写的基类中的函数添加
1 2 3 4 5 | class A { public: virtual void talk() { printf("A "); } }; |
您还应该习惯于在派生类中的重写函数上添加
1 2 3 4 5 6 7 | class B: public A { public: virtual void talk() override { printf("B "); } // ^ Compiler will report an error if base class' function // is not virtual. }; |
。
此外,不能将派生对象分配给基类的实例,否则将发生切片。
1 2 3 4 5 | std::vector<A> vec; /* ... */ B b; /* ... */ vec.push_back(b); // Slicing. Information only in B is lost. |
使用
没有
型
如果不使用指针,则在将对象复制到向量中时,将得到"对象切片"。这会将对象减少到vector模板参数中声明的基类型。所以没有子类,所以没有子类方法可以调用,即使该方法是虚拟的。
型
我认为您缺少的是方法声明中的
型
方法应该是虚拟的。在Java中,默认方法是虚拟的。
1 2 3 4 5 6 7 8 9 10 11 | class A { public: virtual void talk() { printf("A "); } }; class B: public A { public: virtual void talk() override { printf("B "); } //override key word is in C++ 0x and above }; |
号
型
您应该将这些方法声明为
1 2 3 4 5 6 7 8 9 10 11 12 13 | class A { public: virtual void talk() { printf("A "); } virtual ~A(){} }; class B: public A { public: // using virtual is not really necessary here, but it's good for clarity. virtual void talk() { printf("B "); } }; |