C++ Tutorial
Class and Object
Reference
Inheritance and Derivation
Polymorphism and Virtual Functions
Operator Overloading
Template
Exception
Object Oriented Advanced
Input/Output Stream
File Operations
In C++ inheritance, name shadowing occurs when a derived class has a member with the same name as a member in the base class. When this happens, the member of the derived class hides or "shadows" the member of the base class. In this tutorial, we'll cover name shadowing in C++ inheritance and how to avoid it.
To use the iostream
library, include the iostream
header.
#include <iostream>
Create a base class with a function that will be shadowed in the derived class.
class Base { public: void print() { std::cout << "This is the base class print function." << std::endl; } };
Create a derived class with a function that has the same name as the function in the base class.
class Derived : public Base { public: void print() { std::cout << "This is the derived class print function." << std::endl; } };
When calling the print()
function using a derived class object, the derived class version of the function will be called, and the base class version will be shadowed.
int main() { Derived d; d.print(); // Calls the print() function of the derived class return 0; }
Output:
This is the derived class print function.
To call the base class version of the function, use the scope resolution operator ::
.
int main() { Derived d; d.Base::print(); // Calls the print() function of the base class return 0; }
Output:
This is the base class print function.
Another way to avoid name shadowing is by using virtual
functions. If a base class function is declared as virtual
, the compiler will perform a dynamic dispatch, ensuring the correct version of the function is called based on the object type.
Example:
class Base { public: virtual void print() { std::cout << "This is the base class print function." << std::endl; } }; class Derived : public Base { public: void print() override { std::cout << "This is the derived class print function." << std::endl; } }; int main() { Base* base_ptr = new Derived(); // Base class pointer pointing to a derived class object base_ptr->print(); // Calls the derived class print function, since it's declared virtual in the base class delete base_ptr; return 0; }
Output:
This is the derived class print function.
By understanding name shadowing in C++ inheritance, you can avoid issues when working with derived classes and ensure the correct version of a function is called. Using the scope resolution operator or virtual functions, you can control the behavior of your class hierarchy as needed.
Scope resolution operator and name shadowing in C++:
::
) as a mechanism to access hidden or shadowed names in C++.#include <iostream> // Base class class Base { public: int value = 10; }; // Derived class class Derived : public Base { public: int value = 20; void displayValues() { std::cout << "Derived value: " << value << std::endl; // Accessing derived class member std::cout << "Base value (using scope resolution): " << Base::value << std::endl; // Accessing base class member } }; int main() { Derived derivedObj; derivedObj.displayValues(); return 0; }
Preventing ambiguity with name shadowing in C++:
#include <iostream> // Base class class Base { public: int value = 10; }; // Another Base class with a different member class AnotherBase { public: int value = 30; }; // Derived class inheriting from both Base classes class Derived : public Base, public AnotherBase { public: void displayValues() { std::cout << "Base value: " << Base::value << std::endl; // Accessing Base class member std::cout << "AnotherBase value: " << AnotherBase::value << std::endl; // Accessing AnotherBase class member } }; int main() { Derived derivedObj; derivedObj.displayValues(); return 0; }