对不可复制的派生对象进行别名的基准引用的分配

时间:2015-02-05 10:31:56

标签: c++

我与一位同事讨论了将抽象基类标记为不可复制的问题。我没有看到对此的需要,因为基类是抽象的,因此我们不能有base的实例,因此复制基础引用不是问题。派生类可以自行决定是否允许复制。 但是,我的同事向我展示了一个基础参考文献的分配,让我感到非常惊讶。

#include <stdio.h>
struct B
{
    virtual void foo() = 0;
    virtual ~B(){}
};

struct D : public B
{
    D(int i): data(i){}
    void foo() override {printf("%d", data);}
    int data;

    D& operator=(D) = delete;
    D(const D&) = delete;
};

int main()
{
    D d(1);
    D d2(2);
    d.foo();
    d2.foo();

    B& b = d;
    B& b2 = d2;
    b.foo();
    b2.foo();

    b = b2; // what is this doing?
    b.foo();
    b2.foo();

    d.foo();
    d2.foo();
}

上面的代码输出:12121212。我真的不明白这里发生了什么。 b = b2;做了什么?我在这里期待编译错误。

1 个答案:

答案 0 :(得分:3)

您没有定义复制赋值运算符,因此默认为您。

默认值不是virtual,因此它会将B d2子对象的任何成员变量复制到B d子对象1}}。 (B::operator=D::operator=)一无所知。

像这样使用基类operator=会破坏一般情况下的封装;虽然在这种情况下,因为B没有成员变量而且没有基类,所以这一行实际上没有效果。

因此,将B标记为不可复制可能过于防御;因为它会强制你的任何后代类想要复制以跳过箍重新启用复制。