What is wrong with this inheritance?

I just do not understand. Tried on VC ++ 2008 and g ++ 4.3.2

#include <map> class A : public std::multimap<int, bool> { public: size_type erase(int k, bool v) { return erase(k); // <- this fails; had to change to __super::erase(k) } }; int main() { A a; a.erase(0, false); a.erase(0); // <- fails. can't find base class' function?! return 0; } 
+4
source share
9 answers

When you declare a function in a class with the same name but with a different signature from the superclass, then the name resolution rules indicate that the compiler should stop searching for the function that you are trying to call as soon as it finds the first match. After finding a function by name, it applies the rules for resolving overloads.

So what happens, the compiler finds your implementation of erase(int, bool) when calling erase(0) , and then decides that the arguments do not match.

+26
source

1: You should be extremely careful when building containers of the C ++ standard library. This can be done, but since they do not have virtual destructors and other similar subtleties, this is usually the wrong approach.

2: Overload rules here are a bit fancy. The compiler first searches for the derived class, and if it detects any overload with the same name, it stops looking there. It looks only in the base class if no overloads were found in the derived class.

A simple solution is to enter the functions you need from the base class into the namespace of the derived class:

 class A : public std::multimap<int, bool> { public: using std::multimap<int, bool>::erase; // Any erase function found in the base class should be injected into the derived class namespace as well size_type erase(int k, bool v) { return erase(k); } }; 

Alternatively, of course, you could just write a small helper function in a derived class, redirecting to a base class function

+17
source

You have hidden the member function of the erase base class by defining a function in a derived class with the same name but with different arguments.

http://www.parashift.com/c++-faq-lite/strange-inheritance.html#faq-23.9

+9
source

First of all, you should never be fetched from STL containers, because no STL containers define a virtual destructor.
Secondly, see Greg's answer on inheritance.

+6
source

Think about whether you really want to inherit from std :: map. For all the time that I wrote the code, and which is longer than the STL, I never saw an instance where inheriting from std :: container was the best solution.

In particular, ask yourself if your IS class is a multimap or a HAS multimap.

+5
source

Others answered how to solve the syntax problem and why it might be dangerous to derive from standard classes, but it is also worth noting:

Prefer composition for inheritance.

I doubt that you mean that for "A" explicitly relates "is-a" to multimap <int, bool>. C ++ Coding Standards Sutter / Alexandrescu has a whole chapter on this (# 34) and Google points out many good links on this.

There seems to be an SO topic on this topic .

+3
source

For those who use Effective C ++ as a reference to C ++ programming, this issue is addressed in paragraph 33 (Avoid hiding inherited names.) In the book.

+1
source

I agree with the comments of others that you need to be very careful about inheriting from STL classes, and it should almost always be avoided.

However, this problem may arise with some other base class from which it is quite reasonable to inherit.

My question is: why not give your function with two arguments a different name? If he takes different arguments, does it seem to have a slightly different meaning? For instance. erase_if_true or erase_and_delete or something like bool.

+1
source

To replace __super in a portable way, define a typedef at the top of your class as follows:

 typedef std::multimap<int, bool> parent; public: size_type erase(int k, bool v) { return parent::erase(k); } 

Of course, he does not have to be a "parent." It can be any name you like if it is constantly used throughout your project.

0
source

All Articles