调用隐式删除的复制构造函数
Call to implicitly deleted copy constructor
我有以下设置:
class MyClass {
public:
static MyClass Clone(const MyClass& other) {
return MyClass(other, 10);
}
static MyClass CreateNormal(int x, int y) {
return MyClass(int x, int y);
}
// There are a few more factory functions.
private:
// Constructor 1
MyClass(int x, int y) : b_(x, y) {}
// Constructor 2
MyClass(const MyClass& other, int c) : b_(other.b_, c) {}
// And a lot more constructors.
// NotMyClass has its copy constructor deleted.
NotMyClass b_;
}
int main() {
MyClass A(1,2);
MyClass B = MyClass::Clone(A); // ERROR
}
有没有办法在不修改NotMyClass
的情况下解决这个问题? 发生此错误的原因是隐式删除了MyClass
的复制构造函数。有没有办法使用 std::Move(( 来解决这个问题?
我无法删除工厂函数,因为实际类有许多构造函数,并且需要工厂函数才能清晰和理解。
假设 c++11 标准可用,则可以延长工厂方法返回的右值引用的生存期,而不是构造一个新对象,如下所示:
MyClass A(1, 2);
MyClass&& B = MyClass::Clone(A);
补遗: 正如 patatahooligan 在下面的评论中指出的那样,您的MyClass::Clone
版本本身中可能存在复制构造函数调用。这可以/需要重写为
MyClass MyClass::Clone(const MyClass& other) {
return {other, 10};
}
一旦 C++17 带有强制性复制省略,所有这些都将完全没有必要,所以你可以期待这一点。
在 C++03 中,尽管解决方案更长并且需要更多的代码,但仍有可能实现预期的结果。我提供两种选择:
与其创建一组静态方法,我建议使用 tag-dispatch 来表示不同的构造函数含义。这通过使用具有明确名称但不保存数据的类型参数重载构造函数来工作。
struct clone_tag {};
class MyClass {
public:
MyClass(int x, int y) : b_(x, y) {}
MyClass(const MyClass& self, clone_tag) : b_(self.b_, 10) {}
private:
NotMyClass b_;
};
int main() {
MyClass A(1, 2);
MyClass B(A, clone_tag());
}
或者这甚至可以达到真正的工厂模式,其中建造工厂和物体的最终建筑是分开的。这显然需要更多时间来设置,但可以提高代码质量,具体取决于不同构造函数路径的实际数量。
class MyClass {
public:
struct Clone {
Clone(const MyClass& self) : self(self) {}
const MyClass& self;
};
struct Init {
Init(int x, int y) : x(x), y(y) {}
int x, y;
};
MyClass(Init i) : b_(i.x, i.y) {}
MyClass(Clone c) : b_(c.self.b_ , 10) {}
private:
MyClass(const MyClass& other, int c) : b_(other.b_, c) {}
NotMyClass b_;
};
int main() {
MyClass A = MyClass::Init(1, 2);
MyClass B = MyClass::Clone(A);
}
再三考虑,我意识到给出三种不同的选择可能会比不太精确的简短答案引起更多的混乱。因此,我试图按所需的重构工作的顺序列出它们,尽管这只是对真实代码库的猜测。
相关文章:
- C++17复制构造函数,在std::unordereded_map上进行深度复制
- 为什么在C++中使用私有复制构造函数与删除复制构造函数
- 当从函数参数中的临时值调用复制构造函数时
- 如果有一个模板构造函数只有一个泛型参数,为什么我必须有一个复制构造函数
- 为什么需要复制构造函数,在哪些情况下它们非常有用
- 使用仅使用一次的变量调用的复制构造函数.这可能是通过调用move构造函数进行编译器优化的情况吗
- 为什么类中的ostringstream类型的成员会导致";调用隐含删除复制构造函数";错误
- 复制构造函数、赋值运算符C++
- std::ofstream 作为类成员删除复制构造函数?
- 复制构造函数C++无法正确复制指针
- 关于复制构造函数的一个棘手问题
- 为什么调用复制构造函数而不是移动构造函数?
- 填充上编译器生成的复制构造函数之间的不一致
- C++ 对象指针数组的复制构造函数
- C++ 基本 CTOR 说明 - 为什么不调用赋值/复制构造函数
- 防止在复制构造函数中隐式调用基构造函数
- 为用户定义的类正确调用复制构造函数/赋值运算符
- 具有已删除移动和复制构造函数的类的就地构造
- 复制构造函数隐式转换问题
- 复制构造函数中的递归调用