【发布时间】:2018-12-20 12:04:52
【问题描述】:
建议有一个由堆中分配的对象组成的类。
class A
{
public:
A() { m_b = new B; m_c = new C; }
virtual ~A() { delete m_b; delete m_c; }
inline B* b() const { return m_b; }
inline C* c() const { return m_c; }
private:
B* m_b;
C* m_c;
}
哪些设置器最适合此类代码?
我想出了这个,
inline void setB(B* b) const { delete m_b; m_b = b; }
inline void setC(C* c) const { delete m_c; m_c = c; }
但是有一个问题。如果我们添加了一个非堆变量或者只是一个我们不必用这个 setter 删除的变量,它将在下一次调用 setter 后被删除,这种情况会导致错误或意外行为。
我们也不能直接删除对象,因为 getter 有 const 修饰符。此外,它也不安全,因为该类的用户可能不知道内部对象是否分配在堆中。
能否请您解释一下如何将 setter 与堆分配的对象一起使用?
【问题讨论】:
-
与任何其他对象没有什么不同。您有责任管理对象以避免内存泄漏和未定义的行为。不幸的是,没有一个可以按下的神奇按钮,并且始终使这项工作正常进行。没有通用的法则告诉您“如何将 setter 与堆分配的对象一起使用”。这是你需要自己弄清楚的事情。
-
这是一些非常混乱的所有权语义。找出谁应该拥有什么,其余的随之而来。
-
不要编写依赖于堆分配对象的类。编写这样的课程的好理由很少,但有很多不好的理由。如果你解释了为什么你觉得需要这样一个类,那么也许有人可以解释一种更好的方法来设计你的代码。
-
1:不要使用术语“堆”分配的对象,它在 C++ 中没有用(C++ 不是 Java)。有四种类型的对象(自动/静态/动态/线程)存储持续时间。
*也不一定意味着动态分配。 2:Get/Set中断封装更喜欢寻找更好的方式;通常是基于action的方法。 3:不要返回这样的指针,它没有定义对象的所有权语义(因此泄漏或错误删除)。 4:我假设您没有遵守 3/5 规则,因为问题的示例很短。
标签: c++ memory memory-management heap-memory getter-setter