簡體   English   中英

派生對象/智能指針的容器

[英]Container of derived objects / smart pointers

可以說我有:

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
}

當使用指向 Base 的指針向量時,它被切片。 我想我必須使用智能指針,但我無法讓它工作。

我試過類似的東西:

auto tmp = make_shared<const Base> (b);
vec_smart.push_back(shared_ptr<const Base>(b));

但是還是被切了。 我做錯了什么?

編輯:我在基類中有 << 運算符,它在派生類中調用虛擬打印。

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";
}

當我打電話

cout << b;

在 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;
}

這是一個糟糕的設計嗎?

我猜你沒有將Base的相關方法聲明為virtual 嘗試這個:

struct Base
{
  virtual void print(std::ostream& os) const { os << "Base"; }
  virtual ~Base() {}
};

struct Derived1 : Base
{
  void print(std::ostream& os) const { os << "Derived1"; }
};

等等。 注意我在這里只使用了struct來節省我多次輸入public

這是一個工作示例:

#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;
  }

}

輸出:

Base
Derived1

你可以在這里看到它的實際效果。

編輯您的代碼具有未定義的行為,因為您正在存儲指向臨時文件的指針:

Store a("aaaaaaa");
a.Add(Derived("abc", 5));
a.Add(Derived("def", 6));

此版本按預期工作:

Store a("aaaaaaa");
Derived d0("abc", 5);
Derived d1("def", 6);
a.Add(d0);
a.Add(d1);

編輯 2 :來自您的評論:

假設我被迫使用 a.Add(Derived("abc", 5)); 在我的實現中我可以用它做什么?

您可以Add模板:

template <typename T>
void Add(const T& elem)
{
  vec.push_back(new T(elem));
}

或者

template <typename T>
void Add(const T& elem)
{
  vec_smart.push_back(std::make_shared(elem));
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM