Search code examples
c++operator-overloadingusinglanguage-lawyermethod-hiding

Hiding base class method with "using" declaration doesn't work for assignment operator


Below is a simple example of how base methods are available in derived class:

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 =
}

If I add below statements in the body of Derived to hide both the methods, ...

struct Derived : Base {
  //...
private: // hide the below method for `Derived` objects
  using Base::foo;
  using Base::operator =;
}

... then the Base::foo() is hidden (becomes inaccessible) successfully.
But Base::operator = still remains accessible!!

d1.foo(); // error
d1 = d2;  // ok !!

The same phenomena is happening for other operators as well. Here is a demo with g++.

Shouldn't the accessibility rules (applied due to using keyword) apply to the methods and operators in the same way?
If not then what's the significance of the statement: using operator =;, is it simply ignored by the compiler?

Update:

  1. My first thought was that, compiler might be generating its own default Derived::operator =. That's wrong because it uses Base::operator =.
  2. If I use private inheritance, then Base::foo() is automatically hidden (even without using). But no effect on Base::operator =, it still works.

Please note that, I don't want solution for "how to hide it". But would like to understand from language point of view, why the operators are not hidden like other methods.


Solution

  • Compiler will generate a default operator= for Derived class, and this implicit Derived::operator= in turn invokes Base::operator= internally.
    To get rid of this, we need to disable the operator= explicitly:

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