(Figured this was too subjective for SO, so posting here...)

I have some behavior that I can implement in various ways. At least two methods are shows in the code snippet below. Presume that the m_well data member is correctly set somehow at object construction time.

struct Behavior
    virtual bool behavesWell() { return true; }

    bool m_well;
    bool behavesMemberWell() { return m_well; }

struct OtherBehavior : public Behavior
    virtual bool behavesWell() { return false; }

Obviously the one relies upon virtual dispatch, and the other merely the return of a data member.

A third, non-shown method would likely have the non-virtual public member function not return a fixed data member, but instead call a virtual - lets leave that aside for the purpose of this please.

What would lead you to one or other other of these two methods of implementing functionality, such that a user of this class can interrogate an object's behavior?

  • I did one minor edit - and here is another clarification - this is internal code, to be used by a single team at a single site - no "external" users.
    – sdg
    Dec 14, 2010 at 0:14
  • Suggestion: Altought, you can use "struct X {...}" as "public class", I suggest, to use "class Z { public: ... }" in order to identify classes from plain data structures, and get used to add scope modifiers.
    – umlcat
    Mar 23, 2011 at 18:53
  • @umlcat: can you elaborate on the distinction you are drawing between 'classes' and 'plain data' please? why do you think they are important?
    – sdg
    Mar 23, 2011 at 19:54
  • Right. From a programmer point of view, "plain data" means the programming is not thinking about adding unnecesary "overhead" code to the program. Its more conceptual idea, altought, some optimizers may remove the vtable...
    – umlcat
    Mar 23, 2011 at 23:12
  • @umlcat Most classes add no overhead with optimization turned on Mar 9, 2013 at 2:14

6 Answers 6


As far as I can see, you've got a couple of conflicting issues here, which may be clarified if you could tell us for what purpose you're doing this? Is the code going to be used by you/your team, or are you designing an API for consumption by others?

If you're just trying to design a good interface to your functionality, put yourself in the shoes of the clients of your functions - write some unit tests. If when writing the unit tests, anything seems awkward or non-obvious, your design needs improving.

If your class is meant for sub-classing, then you don't want public data members, or protected data members for that matter. Data members that are private can be changed at any time without breaking the sub-classes, whereas changes to protected members (potentially) break sub-classes and changes to public data members (quite likely) break client code. It may seem tedious to have a getter/setter pair of methods to manipulate a data member, but it's worth it if you want to keep the implementation flexible and not design yourself into a corner.

The virtual methods would indicate that you're considering handing the client of your class an interface which would be pure virtual. If this is the case, then you can't have data members in an abstract (pure virtual) class, so that leads you to virtual methods with virtual method calls to get/set data items.


We've got some classes that work that way - there is a type-of function that returns something different in different subclasses. The problem I have is that there's no good way to tell within the debugger, given a BaseClass *.

Use a member variable. The next guy to work on the code may thank you.

  • While you could go poking at the vtable member, all other things being equal, this is a good point. +1. Dec 14, 2010 at 0:40
  • Then use a better debugger, which shows the derived class's data members.
    – D Drmmr
    May 12, 2017 at 18:48

In your example, I would use a data member. It's simple and straightforward.

I would use a virtual method where behavior of the function actually changes in the derived class. In your example, it's still just returning a boolean, even if the value is different. Methods to me should be accomplishing something -- computation or I/O or what have you -- not just being an obtuse interface for data.


The rule of thumb is that all your data members should be private. There are exceptions to this rule, such as simple POD (plain old data) structs that are only passed around or stored, but more often than not it makes sense to keep all data members private.

If you need to give other objects access read access to a data member, then you write a getter. If your class will not have any child classes derived from it, then there is no need to make the getter virtual. The only time you need to make any member function virtual, is when you want to allow a derived class to override it.

  • virtual bool behavesWell() incurs extra processing overhead but, usually, it's a nonissue (e.g. Virtual functions and performance - C++).

  • bool behavesMemberWell() has extra storage requirements: you have an extra bool m_well in every object you create. With the first approach you just have an additional pointer in the vtable (once per class).

If the Behavior class can have more than one virtual function, I'd prefer the first approach (virtual function).


Whether I want to expose raw data or not can be determined by a simple rule: the scope/visibility of the data member. Information hiding is ultimately about reducing scope/visibility to help maintain invariants. Naturally if you have a class which exposes public data members but the class is only used in one little part of your system, then the scope of the data member is already very small. Trying to reduce it any further could be overkill.

Since your case involves inheritance, you have to question not only how many places your data fields will be exposed to as far as clients go, but also how many subclasses you'll have since you'd be exposing this data field for them to tamper with as well.

Now specifically with respect to dynamic dispatch, a general piece of advice I'd offer is to never worry about the performance of dynamic dispatch until it does, indeed, show itself to be a hotspot. It's one of the easiest ways to make your code unnecessarily harder to maintain is obsessing over the cost of indirect function calls. Of course std::sort is much faster than qsort because it can avoid indirect function calls to the comparator, but that's a pathological case where sorting a million elements might invoke 50 million indirect function calls all doing a trivial amount of work each.

So your decision here should have very little to do with performance and much more to do with maintainability. Also the virtual function has the benefit of letting you do some computations to determine whether these behaviors "behaveWell". I'm not sure if that's a practical benefit or not in your case.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.