February 25, 2021
Hot Topics:

What is Shadowing, and Is It True that C++ Does It?

  • By Kate Gregory
  • Send Email »
  • More Articles »

Is This on Purpose?

So now that you've seen this phenomenon in action, how about giving it a name? Actually, it has two. This behavior is often referred to as "hide-by-name" and it's the way C++ is designed to work. It's also referred to as shadowing. It's a language design decision meant to protect you from base class changes. Consider this pair of classes:

class A
   int i;
   void f(int ii);
class B: public A
   void f(long ii, char* ss);

Imagine that you wrote B, you didn't write A, and that these classes live in some sort of distributed world where someone (a library author?) might add functionality to A without your realizing it. You've written your overload to take a long "just in case," but you actually pass ints to it all the time:

char* s = "Hello";
int i=3;

Then, one day, someone adds an overload to the base class that takes an int and a char*. That's a more precise match, so should the compiler suddenly start calling the new base class overload for you? With hide-by-name, all the base class overloads "disappear" when you write any overload in the derived class, guaranteeing that only overloads you wrote will be called—unless you ask for them specifically by using the scope resolution operator (::) as I did earlier with b.A::f(4).

This behavior in C++ makes sense, but it worries some people who feel it violates substitutability. If you're using inheritance properly, your derived classes should meet the IS A test. Everything you can do with a BankAccount you should also be able to do with a SavingsAccount or a RetirementAccount. Hide-by-name doesn't violate this rule, as long as you've cast your derived class pointer or reference to a base class pointer or reference. In code that knows this is a derived object, the derived methods shadow the base methods.

Does C# Shadow? Does VB?

You may wonder whether other object-oriented languages implement hide-by-name like this. Here are those same two classes in C#:

public class A
   protected int i;
   protected String s;

   public A() {s=null;i=-1;}
   public void f(int ii) {i=ii;s="";}
   public void f(String ss) {i=0; s=ss;}
   public void report () { Console.WriteLine("{0} {1}", i,s);}

public class B:  A
   public void nothing() {;}
   public void f(int ii, String ss){i=ii; s=ss;}

And here's a main that uses them:

A a = new A();
B b = new B();

So, here's something weird: This code compiles just fine and runs just fine. C# doesn't use hide-by-name; it uses hide-by-signature. Is that a positive, or a negative? The answer probably varies from project to project. Sometimes you want your derived class protected against changes in the base class; other times you might like still being able to call all the base class methods even though you've added some overloads in the derived class. (In C#, you can use the keyword new to get shadowing, and, in VB.NET, you should use either Overloads or Shadows to tell the compiler what you want. Shadows is the default.)

Where Does this Leave the C++ Programmer?

What should you do if you're in C++? If you want shadowing, do nothing. If you want to be able to call some methods from the base class, write explicit wrappers for them:

   void f(int ii) {A::f(ii);}
   void f(char* ss) {A::f(s);}

This makes your design obvious and undoes the shadowing. This leaves control, as usual for C++, in the hands of the programmer. Now that you know what the default behavior is, you can step up and change it if you want. And, you can add another tally to the "differences between C++ and C#" list, too.

About the Author

Kate Gregory is a founding partner of Gregory Consulting Limited (www.gregcons.com). In January 2002, she was appointed MSDN Regional Director for Toronto, Canada. Her experience with C++ stretches back to before Visual C++ existed. She is a well-known speaker and lecturer at colleges and Microsoft events on subjects such as .NET, Visual Studio, XML, UML, C++, Java, and the Internet. Kate and her colleagues at Gregory Consulting specialize in combining software develoment with Web site development to create active sites. They build quality custom and off-the-shelf software components for Web pages and other applications. Kate is the author of numerous books for Que, including Special Edition Using Visual C++ .NET.

Page 2 of 2

This article was originally published on February 27, 2004

Enterprise Development Update

Don't miss an article. Subscribe to our newsletter below.

Thanks for your registration, follow us on our social networks to keep up-to-date