[英]Container of derived objects / smart pointers
Lets say i have:可以说我有:
class Base {...};
class Derived1 : public Base {...};
class Derived2 : public Base {...};
class Derived3 : public Base {...};
class Store {
public:
void Add(const Base&); //Adds mix of Derived1/2/3
private:
vector<const Base*> vec;
vector<shared_ptr<const Base> > vec_smart;
};
//------------------------------------------------------
void Store::Add(const Base& b){
vec.push_back(&b); //got sliced
}
When using vector of pointers to Base, it got sliced.当使用指向 Base 的指针向量时,它被切片。 I suppose i have to use smart pointers but I cant get it to work.
我想我必须使用智能指针,但我无法让它工作。
I tried something like:我试过类似的东西:
auto tmp = make_shared<const Base> (b);
vec_smart.push_back(shared_ptr<const Base>(b));
But it still got sliced.但是还是被切了。 What Iam doing wrong?
我做错了什么?
EDIT: I have << operator in Base class that calls virtual print in Derived classes.编辑:我在基类中有 << 运算符,它在派生类中调用虚拟打印。
ostream & operator <<(ostream & os, const Base & x) {
x.print(os);
return os;
}
void Base::print(ostream& os) const {
os << "Base";
}
void Derived1::print(ostream& os) const {
os << "Derived1";
}
When i call当我打电话
cout << b;
In Store::Add it outputs fine but when I iterate over vector after it got stored all i get is "Base"在 Store::Add 它输出正常但是当我在它存储后迭代向量时,我得到的是“Base”
ostream & operator <<(ostream & os, const Store & x) {
for (auto it = x.vec.begin(); it != x.vec.end(); ++it) {
os << *(*it) << endl;
}
return os;
}
Is it a bad design?这是一个糟糕的设计吗?
I am going to guess you didn't declare the relevant methods in Base
as virtual
.我猜你没有将
Base
的相关方法声明为virtual
。 Try this:尝试这个:
struct Base
{
virtual void print(std::ostream& os) const { os << "Base"; }
virtual ~Base() {}
};
struct Derived1 : Base
{
void print(std::ostream& os) const { os << "Derived1"; }
};
ans so on.等等。 Note I have only used
struct
here to save me typing public
a few times.注意我在这里只使用了
struct
来节省我多次输入public
。
Here is a working example:这是一个工作示例:
#include <vector>
int main()
{
Base b;
Derived1 d;
std::vector<const Base*> v{&b, &d};
for (auto it = v.cbegin(); it != v.cend(); ++it)
{
std::cout << *(*it) << std::endl;
}
}
Output:输出:
Base
Derived1
You can see it in action here .你可以在这里看到它的实际效果。
Edit Your code has undefined behaviour because you are storing pointers to temporaries:编辑您的代码具有未定义的行为,因为您正在存储指向临时文件的指针:
Store a("aaaaaaa");
a.Add(Derived("abc", 5));
a.Add(Derived("def", 6));
This version works as expected:此版本按预期工作:
Store a("aaaaaaa");
Derived d0("abc", 5);
Derived d1("def", 6);
a.Add(d0);
a.Add(d1);
Edit 2 : from your comments:编辑 2 :来自您的评论:
Lets say Iam forced to use a.Add(Derived("abc", 5));
假设我被迫使用 a.Add(Derived("abc", 5)); What can I do with it in my implementation?
在我的实现中我可以用它做什么?
You could make Add
a template:您可以
Add
模板:
template <typename T>
void Add(const T& elem)
{
vec.push_back(new T(elem));
}
or或者
template <typename T>
void Add(const T& elem)
{
vec_smart.push_back(std::make_shared(elem));
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.