As having same data members in both base and derived classes, it creates a lot of confusion and requires usage of the scope resolution operator to resolve conflicts. So why is it allowed in C++? Can anyone show me the need for this?
-
5Because overshadowing is allowed in general, and there's nothing special about classes. – Cat Plus Plus Aug 30 '13 at 18:43
-
1Do you mean like this? http://coliru.stacked-crooked.com/view?id=3d6fa652a3 – Chemistpp Aug 30 '13 at 19:02
3 Answers
I don't know the precise motivation, but I believe it's a simple extension of few similar cases, where it is inevitable. Consider for example multiple inheritance - many base classes may have the same members, and there is basically nothing you can do about it as the derived class' creator. Even worse for CRTP - you cannot possibly know members of the base class, since it is arbitrary. These cases seem less confusing than the subject of your question, and are much more problematic, as they cannot be simply forbidden without crippling some features. Since the ambiguity problem must be tackled anyway, it seems only natural that this particular case is handled with the same uniform rules.

- 3,226
- 1
- 19
- 21
-
There are also cases where you explicit want overshadowing, like in variadic templates. Like many other features in C++, it can be quite powerful if use correctly. – Vivian Miranda Aug 31 '13 at 00:12
Overshadowing is not always bad. One counterexample where shadowing is very important is when we work with variadic templates (especially tuples)
Example : Consider the following oversimplified implementation of a tuple. This was the first example I saw how to use variadic templates.
template<typename... T> class tuple0;
template<> class tuple0<> {}; // end recursion
template<typename Head, typename... Tail>
class tuple0<Head, Tail...> : public tuple0<Tail...> {
public:
Head head;
};
Suppose now we want to create tuple0<int, double>
and access both elements. Here is a test program that does that
int main()
{
tuple0<int, double>* t1 = new tuple0<int, double>;
t1->head = 7; // set the integer value
std::cout << "integer: " << t1->head << std::endl;
tuple0<double>* t2 = static_cast< tuple0<double>* >(t1);
t2->head = std::cos(2); // set the double value
std::cout << "double: " << t2->head << std::endl;
return 0;
}
Here you can see that without overshadowing, it would be much harder to work with variadic templates. In addition, the get<> method in std::tuple has a similar implementation.

- 2,467
- 1
- 17
- 27
-
That is why I disagree with the statement that " in sensible design, this should never be an issue". In variadic template, overshadowing is the best practice ! :) – Vivian Miranda Aug 30 '13 at 20:02
-
1
-
You misunderstood the sentence *in a sensible design this should never be an issue*. While I would avoid having users access the tuple internals in the first place (by providing helper functions, and thus breaking the dependency on the names I use), this is a sensible design for the `get` function, and shadowing does the right thing, thus it is *not* an issue. – David Rodríguez - dribeas Aug 31 '13 at 15:39
In a sensible design, this should never be an issue. If you are knowingly creating members with the same name as your bases, it is your design that has an issue. If you unknowingly do it, you will not notice.
On the other hand, if this was forbidden at the language level, they the unknowingly part would become a hard error. Consider the use of a framework from which you inherit. Now consider that there is public interface that is well documented, but anything that is private is undocumented. Now you need to inherit from a type (say a Window
) and you have this variable with a beautiful meaningful name that makes all the sense in the world. You add that to your type, run the compiler only to find out that the name was already used in the base type (or somewhere up in the hierarchy)...

- 204,818
- 23
- 294
- 489
-
I got the impression that you argued that overshadowing is never a good practice, which is not true. In variadic templates overshadowing is the best practice in many situations :) – Vivian Miranda Aug 31 '13 at 00:07
-
@ViniciusMiranda: If that is the impression you got I am a horrible writer. Overshadowing is the *only* option that makes sense. Not only in generic code but even in non-generic pure OO code as you might need to use code from others, and you might not even be aware of the names of their data members (from documentation, you could always read the headers). Conflict will arise, and it would be weird to require that you avoid names you might not even know were used, or upgrade to a new version of the library and fail to compile because they use a new name you use requiring you to refactor. – David Rodríguez - dribeas Aug 31 '13 at 15:35
-
Previous I got the impression that you were saying that it is a bad practice, but unavoidable. I think it is clear now. Thanks :) – Vivian Miranda Aug 31 '13 at 16:24