【问题标题】:What is the proper way to have multiple pointers to single object in C++?在 C++ 中拥有多个指向单个对象的指针的正确方法是什么?
【发布时间】:2019-12-10 17:43:14
【问题描述】:

我正在构建 2 个类。 类 A 包含一个私有对象列表 obj_A,比如 list_a。 类 B 包含对象 obj_B 的列表,比如 list_b。 list_b 中的对象将指向 list_a 中的对象(并且需要访问数据但不修改)。 该类的基本版本如下所示:

#include <iostream>
#include <vector>

//obj_A contains data
class obj_A {
  public:
    obj_A(int x) {x_ = x;};     
    void print() const {
      std::cout << "x_ = " << x_ << std::endl;
    };
  private:
    int x_;
};

//A manages list of obj_A
class A {
  public:
    void addObj(obj_A obj_a) {
      list_a_.push_back(obj_a);
    };

    obj_A* getObjPtr(int i) {
      return &list_a_[i];
    }

  private:
    std::vector<obj_A> list_a_;
};

//obj_B contains data related to obj_A
class obj_B {
  public:
    obj_B(obj_A * obj_a) : obj_a_(obj_a) {};
    void printA() const {
      obj_a_->print();
    };
  private:         
    const obj_A * obj_a_;
};

//B manages list of obj_B
class B {
  public:
    void addObj(obj_B obj_b) {
      list_b_.push_back(obj_b);
    };

    void print() const {
      for(auto b : list_b_) {
        b.printA();
      }
    };
  private:
    std::vector<obj_B> list_b_;
};

//simple example
int main( int argc, char** argv ) {
  //make A
  obj_A a_obj_1(1);
  obj_A a_obj_2(2);

  A a;
  a.addObj(a_obj_1);
  a.addObj(a_obj_2);

  //make B
  obj_B b_obj_1( a.getObjPtr(0) );
  obj_B b_obj_2( a.getObjPtr(0) );
  obj_B b_obj_3( a.getObjPtr(1) );

  B b;
  b.addObj(b_obj_1);
  b.addObj(b_obj_2);
  b.addObj(b_obj_3);

  //print stuff
  b.print();

  return 0;
}

据我了解,除非我使用智能指针,否则为单个对象(list_a 中的对象)创建多个指针(list_b 中的对象)是不好的做法。上面的代码是不好的做法吗?关于如何使用智能指针的任何建议?

【问题讨论】:

  • 共享指针是否表示共享所有权?那么std::shared_ptr 可能很合适。否则,你能保证对象的生命周期至少和最后一个指向它的指针一样吗?
  • “创建多个指向单个对象(list_a 中的对象)的指针(list_b 中的对象)是不好的做法,除非我使用智能指针”你从哪里得到的? raw vs smart 与其说你有多少指针,不如说谁拥有指向的对象
  • 通常最好避免多个“拥有”指向单个对象的指针,因为它会混淆何时删除它。 shared_ptr 有点帮助,但我仍然认为这是最后的手段,即使在带有垃圾收集的语言中,这样的事情也会让人困惑。如果您确实需要指针,单个所有者可以使用unique_ptr,这使得shared_ptr 不需要的意图和生命周期变得清晰。
  • 有点跑题了,但请记住,指向 std::vector 中的对象的指针是危险的。当向量增加其容量时,它们都将失效。最好避免以在发生这种情况后最终可能会被使用的方式存储它们。
  • @Ralff std::list 没有同样的问题。插入或删除元素永远不会使指向列表中对象(被删除对象除外)的指针无效。另一种选择是存储指向std::vector 本身的指针/引用以及索引。您使用哪种方法实际上取决于您的用例的具体情况。

标签: c++ oop pointers smart-pointers


【解决方案1】:

list_b 中的对象会指向 list_a 中的对象(需要访问数据但不能修改)

由于它们是只读指针,因此只需将它们设为 const 即可。

作为@foreknownas_463035818 cmets,使它们成为智能指针完全是关于所有权,而不是有多少指针指向单个对象。

【讨论】:

    猜你喜欢
    • 2012-03-03
    • 2010-09-18
    • 2015-06-08
    • 2016-12-27
    • 2016-12-10
    • 2011-07-19
    • 2016-09-25
    • 2021-12-08
    • 1970-01-01
    相关资源
    最近更新 更多