Should you ever use protected member variables?

OopProtected

Oop Problem Overview


Should you ever use protected member variables? What are the the advantages and what issues can this cause?

Oop Solutions


Solution 1 - Oop

> Should you ever use protected member variables?

Depends on how picky you are about hiding state.

  • If you don't want any leaking of internal state, then declaring all your member variables private is the way to go.
  • If you don't really care that subclasses can access internal state, then protected is good enough.

If a developer comes along and subclasses your class they may mess it up because they don't understand it fully. With private members, other than the public interface, they can't see the implementation specific details of how things are being done which gives you the flexibility of changing it later.

Solution 2 - Oop

Generally, if something is not deliberately conceived as public, I make it private.

If a situation arises where I need access to that private variable or method from a derived class, I change it from private to protected.

This hardly ever happens - I'm really not a fan at all of inheritance, as it isn't a particularly good way to model most situations. At any rate, carry on, no worries.

I'd say this is fine (and probably the best way to go about it) for the majority of developers.

The simple fact of the matter is, if some other developer comes along a year later and decides they need access to your private member variable, they are simply going to edit the code, change it to protected, and carry on with their business.

The only real exceptions to this are if you're in the business of shipping binary dll's in black-box form to third parties. This consists basically of Microsoft, those 'Custom DataGrid Control' vendors, and maybe a few other large apps that ship with extensibility libraries. Unless you're in that category, it's not worth expending the time/effort to worry about this kind of thing.

Solution 3 - Oop

The general feeling nowadays is that they cause undue coupling between derived classes and their bases.

They have no particular advantage over protected methods/properties (once upon a time they might have a slight performance advantage), and they were also used more in an era when very deep inheritance was in fashion, which it isn't at the moment.

Solution 4 - Oop

The key issue for me is that once you make a variable protected, you then cannot allow any method in your class to rely on its value being within a range, because a subclass can always place it out of range.

For example, if I have a class that defines width and height of a renderable object, and I make those variables protected, I then can make no assumptions over (for example), aspect ratio.

Critically, I can never make those assumptions at any point from the moment that code's released as a library, since even if I update my setters to maintain aspect ratio, I have no guarantee that the variables are being set via the setters or accessed via the getters in existing code.

Nor can any subclass of my class choose to make that guarantee, as they can't enforce the variables values either, even if that's the entire point of their subclass.

As an example:

  • I have a rectangle class with width and height being stored as protected variables.
  • An obvious sub-class (within my context) is a "DisplayedRectangle" class, where the only difference is that I restrict the widths and heights to valid values for a graphical display.
  • But that's impossible now, since my DisplayedRectangle class cannot truly constrain those values, as any subclass of it could override the values directly, while still being treated as a DisplayedRectangle.

By constraining the variables to be private, I can then enforce the behaviour I want through setters or getters.

Solution 5 - Oop

In general, I would keep your protected member variables to the rare case where you have total control over the code that uses them as well. If you are creating a public API, I'd say never. Below, we'll refer to the member variable as a "property" of the object.

Here's what your superclass cannot do after making a member variable protected rather than private-with-accessors:

  1. lazily create a value on the fly when the property is being read. If you add a protected getter method, you can lazily create the value and pass it back.

  2. know when the property been modified or deleted. This can introduce bugs when the superclass makes assumptions about the state of that variable. Making a protected setter method for the variable keeps that control.

  3. Set a breakpoint or add debug output when the variable is read or written to.

  4. Rename that member variable without searching through all the code that might use it.

In general, I think it'd be the rare case that I'd recommend making a protected member variable. You are better off spending a few minutes exposing the property through getters/setters than hours later tracking down a bug in some other code that modified the protected variable. Not only that, but you are insured against adding future functionality (such as lazy loading) without breaking dependent code. It's harder to do it later than to do it now.

Solution 6 - Oop

At the design level it might be appropriate to use a protected property, but for implementation I see no advantage in mapping this to a protected member variable rather than accessor/mutator methods.

Protected member variables have significant disadvantages because they effectively allow client code (the sub-class) access to the internal state of the base class class. This prevents the base class from effectively maintaining its invariants.

For the same reason, protected member variables also make writing safe multi-threaded code significantly more difficult unless guaranteed constant or confined to a single thread.

Accessor/mutator methods offer considerably more API stability and implementation flexibility under maintenance.

Also, if you're an OO purist, objects collaborate/communicate by sending messages, not reading/setting state.

In return they offer very few advantages. I wouldn't necessarily remove them from somebody else's code, but I don't use them myself.

Solution 7 - Oop

Most of the time, it is dangerous to use protected because you break somewhat the encapsulation of your class, which could well be broken down by a poorly designed derived class.

But I have one good example: Let's say you can some kind of generic container. It has an internal implementation, and internal accessors. But you need to offer at least 3 public access to its data: map, hash_map, vector-like. Then you have something like:

template <typename T, typename TContainer>
class Base
{
   // etc.
   protected
   TContainer container ;
}

template <typename Key, typename T>
class DerivedMap     : public Base<T, std::map<Key, T> >      { /* etc. */ }

template <typename Key, typename T>
class DerivedHashMap : public Base<T, std::hash_map<Key, T> > { /* etc. */ }

template <typename T>
class DerivedVector  : public Base<T, std::vector<T> >        { /* etc. */ }

I used this kind of code less than a month ago (so the code is from memory). After some thinking, I believe that while the generic Base container should be an abstract class, even if it can live quite well, because using directly Base would be such a pain it should be forbidden.

Summary Thus, you have protected data used by the derived class. Still, we must take int o account the fact the Base class should be abstract.

Solution 8 - Oop

In short, yes.

Protected member variables allow access to the variable from any sub-classes as well as any classes in the same package. This can be highly useful, especially for read-only data. I don't believe that they are ever necessary however, because any use of a protected member variable can be replicated using a private member variable and a couple of getters and setters.

Solution 9 - Oop

Just for the record, under Item 24 of "Exceptional C++", in one of the footnotes, Sutter goes "you would never write a class that has a public or protected member variable. right? (Regardless of the poor example set by some libraries.)"

Solution 10 - Oop

For detailed info on .Net access modifiers go here

There are no real advantages or disadvantages to protected member variables, it's a question of what you need in your specific situation. In general it is accepted practice to declare member variables as private and enable outside access through properties. Also, some tools (e.g. some O/R mappers) expect object data to be represented by properties and do not recognize public or protected member variables. But if you know that you want your subclasses (and ONLY your subclasses) to access a certain variable there is no reason not to declare it as protected.

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionJohn ChanningView Question on Stackoverflow
Solution 1 - OopAllain LalondeView Answer on Stackoverflow
Solution 2 - OopOrion EdwardsView Answer on Stackoverflow
Solution 3 - OopWill DeanView Answer on Stackoverflow
Solution 4 - OopdewordeView Answer on Stackoverflow
Solution 5 - OopMichael BishopView Answer on Stackoverflow
Solution 6 - OoprichjView Answer on Stackoverflow
Solution 7 - OoppaercebalView Answer on Stackoverflow
Solution 8 - OopJay StramelView Answer on Stackoverflow
Solution 9 - OophAcKnRoCkView Answer on Stackoverflow
Solution 10 - OopManuView Answer on Stackoverflow