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.

有帮助吗?

解决方案

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

其他提示

Update:
My first thought was that, compiler might be generating its own default Derived::operator =. That's wrong because it uses Base::operator =. Same holds true for other operators as well.

If I use private inheritance, then Base::foo() is automatically hidden (even without using). But no effect on Base::operator =, it still works.

Your first though was correct. You didn't declare a copy assignment operator, so one was implicitly declared for you. You then odr-used that implicitly-declared copy assignment operator, so the compiler provided the implicitly-defined copy assignment operator. The implicitly-defined copy assignment operator of a struct or class performs a memberwise copy assignment of the class's base classes and then it's non-static data members.

That implicitly-defined copy assignment operator is a class member. It doesn't matter one bit that you have hidden the base class copy constructor to the outside world via using or via private inheritance because that base class assignment operator is visible to this implicitly-defined copy assignment operator.

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top