【问题标题】:When does the C++ default assignment operator become unaccessible?C++ 默认赋值运算符何时变得不可访问?
【发布时间】:2009-08-19 12:44:15
【问题描述】:

如果我定义了一个自己的赋值运算符,它的签名与通常生成的默认赋值运算符不同:

struct B;
struct A {
void operator = (const B& b) {
    // assign something
}
};

默认赋值运算符,在这种情况下operator = (A&)(或类似的,如果错误,请纠正我)变得未定义/无法访问?

AFAIK 这对于默认构造函数是正确的,如果我们定义其他构造函数,则默认构造函数不存在。 但我真的不确定其他“魔法”默认值是否属于这种情况。

我问的原因:我想避免通过隐式类型转换意外调用默认的复制构造函数。如果它不存在,就永远不会发生。

【问题讨论】:

    标签: c++


    【解决方案1】:

    没有。 12.8/9 规定类 X 的赋值运算符必须是非静态、非模板,参数类型为 X、X&、X const&、X volatile& 或 X const volatile&。还有一个注释强调模板的实例化不会抑制隐式声明。

    【讨论】:

    • 感谢标准参考!这实际上比我的例子更能说明问题。
    • @Neil,您想知道 =default 的用途。一个是明确可用的内容,另一个是更改可访问性,第三个是它允许实现不内联,同时确保类的演变不会破坏它。另一个理由是,该功能的范围比分配范围更广,即使它没有用,也没有动力做出例外。
    • 谢谢 - 这非常有用。我真正喜欢 SO 的不是回答问题、获得代表等,而是学习新东西!
    【解决方案2】:

    由于A& operator=( B& ) 没有A& operator=( const A& ) 的签名,这对合成赋值运算符没有任何作用。

    看看this snippet at codepad.org - 只要一个例子算作证明。

    用它试驾Comeau也显示A& operator=( const A& )是合成的。

    【讨论】:

    • 非常有趣的例子。确保将默认的复制赋值运算符设为私有。
    【解决方案3】:

    AFAIK 这对于不存在的默认构造函数是正确的,如果我们定义了其他构造函数。但我真的不确定其他“魔法”默认值是否属于这种情况。

    默认的复制构造函数不会受到提供其他构造函数的影响……

    我问的原因:我想避免通过隐式类型转换意外调用默认的复制构造函数。如果它不存在,就永远不会发生。

    ... 或赋值运算符。例如:

        class A {
                private:
                A& operator= ( const A& a );    // private here means: forbidden operator
                public:
                A( int i ) {}
        };
    
        int main () {
                A a(2);
                A b(a);         // copy constructor syntax 1
                A c = a;        // copy constructor syntax 2
                // Forbidden: A d;
                // Forbidden: c = a;
        }
    

    要禁用默认的复制构造函数,请将其(当然不需要实现)声明为私有。关于您的用例,您可能还想看看关键字“explicit”来禁止自动类型转换。

    【讨论】:

      猜你喜欢
      • 2013-08-09
      • 2015-02-25
      • 1970-01-01
      • 2012-11-26
      • 1970-01-01
      • 2011-05-02
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多