我应该如何构造相互依赖的C++成员
How should I construct C++ members that depend on each other?
我有一个使用库进行通信的类,如下所示:
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) 功能-您需要多态类型吗?Topic
、Reader
和Writer
会被继承吗?如果是,则应该使用指针来防止对象切片。
2) LogicalTalker
是成员(对象)的真正所有者,还是只指向多个类之间共享的一些对象?
老答案
另一种选择是使用智能指针作为成员。通过这种方式,您仍然具有自动内存管理的优势。
但是,如果你了解C++,你同事的论点是无效的,后一个选项也不错。成员按照在class
中声明的顺序进行初始化。因此m_Topic
将首先被初始化,m_Reader
将其次被初始化,最后m_Writer
将被初始化。如果初始化顺序很重要(代码气味),只需重新排序类定义中的成员即可。
这在很大程度上取决于如何使用这些类,但通常情况下,堆分配越少越好,所以我倾向于对包含所有new
的构造函数表示不满。对成员初始化顺序的依赖真的是个问题吗?我很难想象为什么会这样。
如果您使用指针,那么使用智能指针是合理的,std::unique_ptr
是规范的选择。
这实际上取决于您的需求
指针版本的更灵活
- 对象可能为null
- 物品可以交换、拿走
但是
- 你必须注意正确的销毁(好吧,智能指针会有所帮助)
- 在32位内存环境中,您需要更多的内存,至少3*4字节,可能更多是由于内存管理的实现细节,很可能是两倍的数字。当你有很多小东西的时候会很疼
指针模型是一个相当
- 汽车和车轮状况(可更换)
成员模型是一个相当
- 房屋和房间情况(如果不修改房屋,就无法拆除房间)
相关文章:
- 将成员变量添加到共享库中的类中,不会破坏二进制兼容性吗
- 对RValue对象调用的LValue ref限定成员函数
- 为什么使用 "this" 指针调用派生成员函数?
- 具有奇怪重复模板模式的派生类中的成员变量已损坏
- 助记符和指向成员语法的指针
- 用于访问容器<T>数据成员的正确 API
- 内置函数可查看CPP中的成员变量
- 是否可以初始化不可复制类型的成员变量(或基类)
- 如果C++类在类方法中具有动态分配,但没有构造函数/析构函数或任何非静态成员,那么它仍然是POD类型吗
- 找不到成员对象:没有名为get_event()的成员,也处理多态性和向量
- 嵌套在类中时无法设置成员数据
- 为什么在没有显式默认构造函数的情况下,将另一个结构封装在联合中作为成员的结构不能编译
- 将函数类成员映射到类本身内部
- 基于另一个成员参数将函数调用从类传递给它的一个成员
- 将Ref对象作为类成员
- 将包含C样式数组的对象初始化为成员变量(C++)
- 静态数据成员的问题-修复链接错误会导致编译器错误
- 将公共但非静态的成员函数与ALGLIB集成
- 多成员Constexpr结构初始化
- 我们可以访问一个不存在的联盟的成员吗