Hy,我想问一个令我困惑的问题。
我有一个这样的课:
class A {
private:
std::vector<Object*>* my_array_;
...
public
std::vector<Object*>& my_array(); // getter
void my_array(const std::vector<Object*>& other_array); // setter
};
我想根据您的经验问您,以(可能的)安全方式实施setter和getter的正确方法是什么。
我想到的第一个解决方案如下:
首先,当我实现setter时,我应该: A)检查输入不是指我已经拥有的数据结构; B)释放my_array_指向的所有对象的内存 C)复制other_array指向的每个对象并将其副本添加到my_array_ D)最后结束这个功能。
getter可能会生成内部数组的副本,以防万一。
问题很多: - 这种策略是否过度杀伤? - 它真的可以避免问题吗? - 有人真的使用它还是有更好的方法?
我试图寻找这个问题的答案,但没有发现任何特别关注这个问题。
使用智能指针是一个非常好的答案,我感谢你们两个......似乎我不能给不止一个“有用的答案”,所以我提前道歉。 : - )
然而,从你的答案中提出了一个新的疑问。 当我使用包含unique_ptr的向量对象时,我将不得不定义一个深度复制构造函数。有没有比使用迭代器复制对象向量中的每个元素更好的方法,因为现在我们使用智能指针?
答案 0 :(得分:1)
我通常建议不要使用指向矢量的指针作为成员,但是根据你的问题,它似乎在多个实例之间共享。
那就是说,我会选择:
class A {
private:
std::shared_ptr<std::vector<std::unique_ptr<Object> > > my_array_;
public
std::shared_ptr<std::vector<std::unique_ptr<Object> > > my_array(); // getter
void my_array(std::shared_ptr<std::vector<std::unique_ptr<Object> > > other_array); // setter
};
无需检查,无内存管理问题。
如果内部Object
也已共享,请使用std::shared_ptr
代替std::unique_ptr
。
答案 1 :(得分:1)
我认为你将指向 std::vector
的指针作为数据成员过度复杂化;请记住,C ++不是Java(C ++比“参考”更基于“价值”)。
除非有充分的理由使用指向std::vector
的指针作为数据成员,否则我只使用“按值”存储的简单std::vector
。
现在,关于Object*
中的vector
指针,您应该问自己:那些观察指针还是拥有指针?
如果vector
只是观察 Object
(并且它们由其他人拥有,如对象池分配器或其他东西),您可以使用原始指针(即简单Object*
)。
但是,如果向量在Object
上有一些所有权语义,则应使用shared_ptr
或unique_ptr
智能指针。如果向量是Object
个实例的唯一所有者,请使用unique_ptr
;否则,使用shared_ptr
(使用引用计数机制来管理对象生存期)。
class A
{
public:
// A vector which owns the pointed Objects
typedef std::vector<std::shared_ptr<Object>> ObjectArray;
// Getter
const ObjectArray& MyArray() const
{
return m_myArray
}
// Setter
// (new C++11 move semantics pattern: pass by value and move from the value)
void MyArray(ObjectArray otherArray)
{
m_myArray = std::move(otherArray);
}
private:
ObjectArray m_myArray;
};