Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Member function not inherited? [duplicate]

Tags:

c++

This is my code

class B {
public:
  virtual void insert(int t, int p) = 0;

  void insert(int t) {
    insert(t, 0);
  }
};

class D : public B {
public:
  void insert(int t, int p) { }

};

int main() {
  D d;
  d.insert(1);
}

which won't compile. Sure, it will if I say d.B::insert(1) in main, but why is this incorrect as is? Thanks.

like image 734
J Kay Avatar asked Jun 28 '16 18:06

J Kay


People also ask

Which member function Cannot be inherited?

Constructor cannot be inherited but a derived class can call the constructor of the base class.

Which operator is not inherited by derived class?

No operator= can be declared as a nonmember function. It is not inherited by derived classes.

Why friend function is not inherited?

No, friend functions are not inherited. Why would a base class function work on a derived class object? Because friend function is using the data members available in base class only. Not the data members of derived class .

Can private member functions be inherited?

private methods are not inherited.


1 Answers

This is because in this case base class functions are not included in overload resolution. Similar situation is with functions declared in inner scope - they do not overload functions declared in outer scope (see examples below). You can imagine that derived class scope is nested inside base class scope.

Once compiler has found D::insert candidate it will not look further in base class. If there were no D::insert then compiler will look into base class for insert method to call. You can fix this by introducing insert function names from base class with:

using B::insert;

this will introduce all the B::insert overloaded functions in derived class. Or as you say, you can explicitly call base class method with:

d.B::insert(1) 

Sample code to how overloading works in the same way in other contexts:

namespace Outer {
  void foo(double d) {
    std::cout << "Outer::foo(double d)\n";
  }
  namespace Inner {  
    //using Outer::foo; // uncomment to see "Outer::foo(double d)" in output
    void foo(int n) {
        std::cout << "Inner::foo(int n)\n";
    }
    void callMe() {
        foo(1.1);
    }
  }   
}

int main() {
    Outer::Inner::callMe(); // Outputes: Inner::foo(int n)
}

or:

void foo(std::string s) {
    std::cout << "foo(std::string s)\n";
}

void foo(double d) {
    std::cout << "foo(double d)\n";
}

void foo(int n) {
    std::cout << "foo(int n)\n";
}

int main() {
    void foo(int d); // comment out to see foo(double d) in output
    foo(1.1); // outputs: "foo(int n)", foo(double d) is hidden
    //foo("hello"); // ups, it wont compile - name lookup in c++ happens before type checking
                  // commenting out `void foo(int d);` above will fix this.
}
like image 141
marcinj Avatar answered Oct 21 '22 16:10

marcinj