在另一个类的移动构造函数中移动类(没有默认构造函数)

时间:2014-08-06 15:37:55

标签: c++

所以我有一个删除了复制ctor /赋值的类,没有默认的ctor,并且有移动ctor / assignment:

class A {
  int data_ = 0;

public:
    A(const A& other) = delete;
    A& operator=(const A& other) = delete;

    A(int data) : data_(data) {}
    ~A() {}

    A(A&& other) { *this = std::move(other); }
    A& operator=(A&& other) {
        if (this != &other) {
            data_ = other.data_;
            other.data_ = 0;
        }
        return *this;
    }
};

我有一个包含A:

的B类(也没有默认ctor)
class B {
    A a;

public:
    B(const B& other) = delete;
    B& operator=(const B& other) = delete;

    B(int data) : a(data) {}
    ~B() {}

    B(B&& other) { *this = std::move(other); }
    B& operator=(B&& other) {
        if (this != &other) {
            a = std::move(other.a);
        }
        return *this;
    }
};

现在的问题是B移动ctor不会编译,因为他说没有A的默认构造函数,这真的很烦人,我不希望他在B上调用移动ctor时创建一个新的A实例,我想要它移动它!

所以我能做的两件事:

B(B&& other) : a(std::move(other.a)) { *this = std::move(other); }

这不会起作用,因为在移动任务中他会再次尝试移动A ..如果“this ==& other == true”他现在会从他自己制造A垃圾中移动A ..

另一种方式:

制作默认私人A ctor。让A的B朋友,但听起来很丑陋和丑陋...... 处理这种情况的最佳方法是什么?我真的想避免为A创建默认构造函数。

提前感谢。

2 个答案:

答案 0 :(得分:1)

解决方案是:

class A {
  int data_ = 0;

public:
    A(const A& other) = delete;
    A& operator=(const A& other) = delete;

    A(int data) : data_(data) {}
    ~A() {}

    A(A&& other) : data_(other.data_) { other.data_ = 0; }
    A& operator=(A&& other) {
        if (this != &other) {
            data_ = other.data_;
            other.data_ = 0;
        }
        return *this;
    }
};

class B {
    A a;

public:
    B(const B& other) = delete;
    B& operator=(const B& other) = delete;

    B(int data) : a(data) {}
    ~B() {}

    B(B&& other) : a(std::move(a)) {  }
    B& operator=(B&& other) {
        if (this != &other) {
            a = std::move(other.a);
        }
        return *this;
    }
};

虽然,因为A只包含一个int,所以它不会比复制产生更好的性能......

答案 1 :(得分:0)

由于您的班级A中声明了B的对象,因此您需要在构建B时创建它。 C ++中的普通对象不能没有值,也无法创建(因为没有默认的构造函数)。

要解决您的问题,请指向a,其值为0,因此无需在构造函数中创建。改变这一行:

A a;

进入这个:

private:
    A *a = 0;