Reputation: 101
we have two classes: Base and Derived. There is a function in Base class called PrintValue() which has been defined as protected. Derived class inherits this function from Base class, but it is able to change its access specifier to public by declaring it in the public section. My question is: Is this a good software engineering practice? why is Derived class, which inherits a function from Base class, able to change the access level of that function to public, which has already been declared as protected by Base class. this way, in the main function you can declare an object of Derived class and access the protected function of Base class and this is against the expectation of Base class.
class Base
{
private:
int m_nValue;
public:
Base(int nValue)
: m_nValue(nValue)
{
}
protected:
void PrintValue() { cout << m_nValue; }
};
class Derived: public Base
{
public:
Derived(int nValue)
: Base(nValue)
{
}
// Base::PrintValue was inherited as protected, so the public has no access
// But we're changing it to public by declaring it in the public section
Base::PrintValue;
};
int main()
{
Derived cDerived(7);
// PrintValue is public in Derived, so this is okay
cDerived.PrintValue(); // prints 7
return 0;
}
Upvotes: 2
Views: 2398
Reputation: 73530
If your function shouldn't be used by outside world, make it private. This is especially recommended, if it belongs to the internals of your base class and you want to keep freedom to change implementation details, or if a call by outside world could put your object in an unstable state.
class Base {
...
private: // <==== HIDE DETAILS YOU DO NOT WANT TO EXPOSE
void PrintValue() { std::cout << m_nValue; }
};
class Derived : public Base {
...
Base::PrintValue; // <===NOW IT CAN'T COMPILE BECAUSE ACCESS IS PRIVATE !
};
If you've chosen to make your function protected, it's because you want to give away the freedom to use it to its derived classes. But you must accept the rules of the game: with this freedom, you also give away the freedom to expose it, either directly (as you showed) or indirectly through an own function that calls the protected function. Both cases aren't so different by the way: in the end your base function can be triggered by an outsider to the base class !
From a software engineering point of view, as soon as you make a function protected, you expose it to other users (of course much more limited than public exposure, but still much more exposed than private), and you create expectation about some stability of the API. So to quote Scott Meyers: "protected is no more encapsulated than public."
Upvotes: 2
Reputation: 46647
You can argue that Base
declaring PrintValue
protected
is like saying: "I trust deriving classes to use this member correctly". So if Derived
decides to expose it publicly, it is fine provided all contractual guarantees for PrintValue
are maintained.
In terms of good practice, I would strongly prefer adding a public member to Derived
that internally calls the protected base method.
Upvotes: 4