如何将我的子类中的向量向上转换为超类,以便我可以使用一个指针来修改和浏览向量中的对象?提前谢谢!
class S { ... };
class A : public S { ... };
class B : public S { ... };
class C : public S { ... };
int main(){
vector<A> aVec;
A a;
a.addList(aVec, ...some attributes...); //add objects into aVec using a function in class S
a.addList(aVec, ...some attributes...);
vector<B> bVec;
B b;
b.addList(bVec, ...some attributes...); //add objects into bVec using a function in class S
vector<C> cVec;
C c;
c.addList(cVec, ...some attributes...); //add objects into cVec using a function in class S
}
答案 0 :(得分:3)
执行此操作的一种方法是拥有std::vector<std::unique_ptr<S>>
并创建std::unique_ptr<S>(new A)
之类的对象,并将其存储在适当的矢量中。
使用unique_ptr
而不仅仅是原始指针将确保您的对象被正确销毁,就像它们直接存储在vector
中一样。
答案 1 :(得分:1)
您必须创建vector<S*>
,并在其中插入A*
,B*
或C*
类型的元素。
在c ++中,如果你想使用多态,你必须通过指针来做。不幸的是,这在任何手册中都没有突出显示。我很惊讶它以这种方式工作。
答案 2 :(得分:0)
没有办法直接做你要求的事。
原因是派生类实例可以拥有比基类实例更多的成员。因此,三个派生类和基类都可以作为内存布局而不同,并且没有单个指针类型可以处理它。
一种可能的解决方案是添加一个间接级别,只管理指向实例而不是实例的指针。这样你甚至可以创建一个异构向量,其中每个元素都可以引用任何子类。
通常,使用“智能指针”而不是原始指针来处理生命周期问题以避免在删除后泄漏或使用对象被认为是个好主意。
答案 3 :(得分:0)
答案是作为对以下示例的评论给出的。您可以在代码的末尾看到如何编译它。 (compile-command
。)请下次给出你所拥有的实例!
以下代码的替代方法是为您的向量使用模板算法。
#include <vector>
#include <memory>
#include <algorithm>
#include <iostream>
struct S {
public:
int el;
virtual ~S() {}; // you need this to be polymorphic
};
struct A : public S {
public:
int elA;
virtual ~A() {};
};
struct B : public S {
virtual ~B() {};
};
int main(){
/**
To write generic algorithms you normally use pointers to objects
of the base class and down-cast when you store elements.
*/
std::vector<std::shared_ptr<S> > aVec;
A a;
a.el = 2;
a.elA = 3;
/**
If you do not want to keep local storrage for the objects you
normally use the heap for the objects and store smart
pointers with reference counting for the objects in the vector.
Note, shared_ptr are C++11.
Note also, that normally you should avoid to use `new` explicitly.
*/
aVec.push_back(std::shared_ptr<S>(dynamic_cast<S*>(new A(a))));
aVec.push_back(std::shared_ptr<S>(dynamic_cast<S*>(new A(a))));
/**
You can then treat the objects in the vector like such of type S:
*/
std::for_each(aVec.begin(),aVec.end(), [](std::shared_ptr<S> p) { std::cout << "el=" << p->el << "\n"; });
/**
You recover the vector elements by back-casting them to the type A*.
But, test the recovered pointer.
If the cast fails (because the element was not really of type A) then dynamic_cast delivers a null-pointer.
*/
std::for_each(aVec.begin(),aVec.end(), [](std::shared_ptr<S> p) {
A* pa = dynamic_cast<A*>(p.get());
if(pa) {
std::cout << "elA=" << pa->elA << "\n";
}
});
}
/**
Local Variables:
compile-command: "g++ --std=c++11 test.cc -o test.exe; ./test.exe"
End:
*/
如果您有兴趣,还可以查看“为什么我不能将vector<Apple*>
分配给vector<Fruit*>
”的答案?在http://www.stroustrup.com/bs_faq2.html。你的问题很相似。对于你来说vector<Apple>
到vector<Fruit>
造成同样的问题。