随着std::unique_ptr
等最新C ++类的使用越来越多,我发现很多默认情况下无法复制使用它们的成员。这很好,因为它们不能被复制:如果父类必须是可复制的,那些成员需要明确地处理。
但是我发现重载复制构造函数/运算符不方便。每个成员都需要明确复制,即使是那些不需要特殊处理的成员。而且,当添加成员时,代码维护者必须记住将此成员添加到复制功能中。我发现这个代码维护者未能做到这一点的可能性接近于我的那个。 (我知道至少有一个可以拥有operator = rely on the copy constructor)。
所以我想知道是否有有效的方法来重载复制构造函数/运算符,这样就不需要为默认复制的成员编写代码。
我能想到的一个解决方案是将类分成两部分:放入一个基类成员,默认复制,其余部分放在子类中;仅限子类的重载副本。我觉得这有点不雅,我相信它有缺点。
另一种方法是将不可复制的对象包装到类中,这些类在复制时构造底层的非可复制对象。这可能更好,但只有当这些对象可以独立于其他父类成员进行初始化时才有用。
如果有人有想法或经验可以分享他们如何解决这个问题,我很乐意听到。
答案 0 :(得分:7)
将unique_ptr
成员包装在另一种具有特殊行为的类型中(即克隆指针,或任何适当的行为)。或使用clone_ptr
代替unique_ptr
。
然后只声明你的类'复制构造函数和复制赋值运算符为默认值。
这是一种通用模式,当您只需要某些成员的非默认行为时非常有用:不要手动实现整个复制构造函数,必须为每个成员指定行为,使用包装器将特殊行为添加到需要特殊行为的成员,然后包含类只依赖于默认值。
事实上,这只是使用像unique_ptr
甚至std::string
这样的RAII类型作为成员的概括。而不是必须为记住delete
指针成员或free
每个char*
的包含类编写析构函数,而是让每个成员做正确的事,并且包含的类变为万无一失。
这可能更好,但只有当这些对象可以独立于其他父类成员进行初始化时才有用。
它仍然可能,但是包装器可能需要一个指向父类的指针,因此它可以到达其他成员,这会使事情稍微复杂化。
如果您拥有无法独立初始化的相关成员,则可以将相关成员分组为另一种类型,这些类型对所有成员一起做正确的事情。如果有其他成员可以独立初始化,那么仍然可以更容易将它们组合成父类。
同样,你使每个子对象独立且万无一失,因此它们可以像简单的构建块一样组成。如果有成员不是独立的,他们应该属于同一个构建块。