Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/cassandra/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 使用“隐藏基类方法”;使用;声明不';不为赋值运算符工作_C++_Operator Overloading_Using_Language Lawyer_Method Hiding - Fatal编程技术网

C++ 使用“隐藏基类方法”;使用;声明不';不为赋值运算符工作

C++ 使用“隐藏基类方法”;使用;声明不';不为赋值运算符工作,c++,operator-overloading,using,language-lawyer,method-hiding,C++,Operator Overloading,Using,Language Lawyer,Method Hiding,下面是如何在派生类中使用基本方法的简单示例: struct Base { void foo (); Base& operator = (const Base&); }; struct Derived : Base { // ... }; int main () { Derived d1, d2; d1.foo(); // calls Base::foo d1 = d2; // calls Base::operator = } 如果我在Deriv

下面是如何在派生类中使用基本方法的简单示例:

struct Base {
  void foo ();
  Base& operator = (const Base&);
};

struct Derived : Base {
  // ...
};

int main () {
  Derived d1, d2;
  d1.foo();  // calls Base::foo
  d1 = d2;   // calls Base::operator =
}
如果我在
Derived
的主体中添加以下语句以隐藏这两个方法

struct Derived : Base {
  //...
private: // hide the below method for `Derived` objects
  using Base::foo;
  using Base::operator =;
}
。。。然后,成功隐藏了
Base::foo()

但是
Base::operator=
仍然可以访问

同样的现象也发生在其他运营商身上。这是一本书

可访问性规则(由于
使用
关键字而应用)不应该以同样的方式应用于方法和运算符吗?
如果不是,那么语句的意义是什么:
usingoperator=,编译器是否忽略了它

更新

  • 我的第一个想法是,编译器可能正在生成自己的 默认值
    派生::运算符=
    。这是错误的,因为它使用
    Base::operator=
  • 如果我使用
    private
    继承,那么
    Base::foo()
    将自动 隐藏(即使没有
    使用
    )。但对
    Base::operator=
    没有影响, 它仍然有效

  • 请注意,我不想要“如何隐藏它”的解决方案。但我想从语言的角度理解,为什么操作符不像其他方法一样隐藏。

    编译器将为派生类生成一个默认的
    操作符=
    ,这个隐式的
    派生::操作符=
    反过来在内部调用
    基::操作符=

    要消除此问题,我们需要显式禁用
    运算符=

    struct Derived : Base {
      private: Derived& operator = (const Derived&);  // C++03 way
    };
    
    struct Derived : Base {
      Derived& operator = (const Derived&) = delete;  // C++11 way
    };
    

    编译器将为派生类生成一个默认的
    运算符=
    ,这个隐式的
    派生的::运算符=
    依次在内部调用
    基::运算符=

    要消除此问题,我们需要显式禁用
    运算符=

    struct Derived : Base {
      private: Derived& operator = (const Derived&);  // C++03 way
    };
    
    struct Derived : Base {
      Derived& operator = (const Derived&) = delete;  // C++11 way
    };
    
    更新:
    我的第一个想法是,编译器可能正在生成自己的默认派生::运算符=。这是错误的,因为它使用
    Base::operator=
    。其他运营商也是如此

    如果我使用私有继承,那么
    Base::foo()
    将自动隐藏(即使不使用)。但对
    Base::operator=
    没有影响,它仍然有效

    你的第一个想法是正确的。您没有声明复制赋值运算符,因此隐式为您声明了一个。然后,odr使用隐式声明的复制赋值运算符,因此编译器提供了隐式定义的复制赋值运算符。结构或类的隐式定义的复制赋值运算符执行类基类的成员复制赋值,然后执行非静态数据成员的复制赋值

    隐式定义的复制赋值运算符是类成员。通过
    使用
    或通过私有继承将基类复制构造函数隐藏到外部世界一点都不重要,因为该基类赋值运算符对该隐式定义的复制赋值运算符可见

    更新:
    我的第一个想法是,编译器可能正在生成自己的默认派生::运算符=。这是错误的,因为它使用
    Base::operator=
    。其他运营商也是如此

    如果我使用私有继承,那么
    Base::foo()
    将自动隐藏(即使不使用)。但对
    Base::operator=
    没有影响,它仍然有效

    你的第一个想法是正确的。您没有声明复制赋值运算符,因此隐式为您声明了一个。然后,odr使用隐式声明的复制赋值运算符,因此编译器提供了隐式定义的复制赋值运算符。结构或类的隐式定义的复制赋值运算符执行类基类的成员复制赋值,然后执行非静态数据成员的复制赋值


    隐式定义的复制赋值运算符是类成员。通过
    使用
    或通过私有继承将基类复制构造函数隐藏到外部世界一点都不重要,因为该基类赋值运算符对该隐式定义的复制赋值运算符可见。

    这是因为没有理由查找基类运算符。派生类已经隐式地有了一个完全可用的赋值运算符。@KerrekSB,我已经在问题中澄清了这一部分。它不使用编译器生成的
    运算符=
    。似乎还有其他原因。让我们暂时不使用编译器,它并没有真正发挥作用。隐式定义的
    运算符=
    执行成员式赋值,还调用基类的赋值运算符,因此您可能不一定能够判断。如果将基类赋值运算符设为私有,则隐式定义的派生赋值运算符定义为已删除。@KerrekSB,是的,你的第二条评论对我来说很有意义。编译器应该调用隐式的
    Derived::operator=
    ,它反过来隐式地调用
    Base::operator=
    。这是因为没有理由查找基运算符。派生类已经隐式地有了一个完全可用的赋值运算符。@KerrekSB,我已经在问题中澄清了这一部分。它不使用编译器生成的
    运算符=
    。似乎还有其他原因。让我们暂时不使用编译器,它并没有真正发挥作用。隐式定义的
    运算符=
    执行成员式赋值,还调用基类的赋值运算符,因此您可能不一定能够判断。如果将基类赋值运算符设为私有,则隐式定义的派生赋值运算符定义为已删除。@KerrekSB,是的,你的第二条评论对我来说很有意义。编译器应该调用隐式
    Derived::operator=
    ,该操作符反过来隐式调用
    Ba