我应该如何构造相互依赖的C++成员

How should I construct C++ members that depend on each other?

本文关键字:C++ 成员 依赖 何构造 我应该      更新时间:2023-10-16

我有一个使用库进行通信的类,如下所示:

class Topic {
  Topic( Type T, String name );
};
class Reader {
  Reader (Topic, String name);
};
class Writer {
  Writer (Topic, String name);
};

我想做一个这样的谈话类:

Talker (Type T, String name);

并使用构造函数生成成员Writer和Reader。

我在用指针做这件事之间左右为难:

class Talker {
  Topic* m_Topic;
  Reader* m_Reader;
  Writer* m_Writer;
  Talker (Type T, String name) {
    m_Topic = new Topic (T, generateTopicName(name));
    m_Reader = new Reader (m_Topic, generateReaderName(name));
    m_Writer = new Writer (m_Topic, generateWriterName(name));
  }
};

直接对战:

class Talker {
  Topic m_Topic;
  Reader m_Reader;
  Writer m_Writer;

  Talker (Type T, String name) :
    m_Topic(T, name),
    m_Reader(m_Topic, generateReaderName(name)),
    m_Writer(m_Topic, generateWriterName(name))
  {}
};

我和一位同事交谈过,显然后者很糟糕,因为它依赖于成员初始化顺序。然而,它也有一个工作的自动复制构造函数。

这样做的更好方法是什么,尤其是在成员对象列表变长的情况下?

这样的决定不应该基于同事提出的论点,因为这是一个无效的论点。即使有对象成员,您也可以控制初始化的顺序——请参阅我的最后一段。决策应基于:

1) 功能-您需要多态类型吗?TopicReaderWriter会被继承吗?如果是,则应该使用指针来防止对象切片。

2) LogicalTalker是成员(对象)的真正所有者,还是只指向多个类之间共享的一些对象?

老答案

另一种选择是使用智能指针作为成员。通过这种方式,您仍然具有自动内存管理的优势。

但是,如果你了解C++,你同事的论点是无效的,后一个选项也不错。成员按照在class中声明的顺序进行初始化。因此m_Topic将首先被初始化,m_Reader将其次被初始化,最后m_Writer将被初始化。如果初始化顺序很重要(代码气味),只需重新排序类定义中的成员即可。

这在很大程度上取决于如何使用这些类,但通常情况下,堆分配越少越好,所以我倾向于对包含所有new的构造函数表示不满。对成员初始化顺序的依赖真的是个问题吗?我很难想象为什么会这样。

如果您使用指针,那么使用智能指针是合理的,std::unique_ptr是规范的选择。

这实际上取决于您的需求

指针版本的更灵活

  • 对象可能为null
  • 物品可以交换、拿走

但是

  • 你必须注意正确的销毁(好吧,智能指针会有所帮助)
  • 在32位内存环境中,您需要更多的内存,至少3*4字节,可能更多是由于内存管理的实现细节,很可能是两倍的数字。当你有很多小东西的时候会很疼

指针模型是一个相当

  • 汽车和车轮状况(可更换)

成员模型是一个相当

  • 房屋和房间情况(如果不修改房屋,就无法拆除房间)