Is virtual methods overhead significant? - c++

I have somewhat complicated inheritance structure which is mainly there to avoid code-duplicating and to facilitate common interface for various classes. It relies on virtual and non-virtual inheritance and looks more or less like this:
class AbstractItem
{
//bunch of abstract methods
};
class AbstractNode : virtual public AbstractItem
{
//some more virtual abstract methods
};
class AbstractEdge : virtual public AbstractItem
{
//yet some different virtual abstract methods
};
and then some "real" classes like this
class Item : virtual public AbstractItem
{
//implements AbstractItem
};
class Node : public Item, public AbstractNode
{
//implements AbstractNode
};
class Edge : public Item, public AbstractEdge
{
//implemetns AbstractEdge
};
and this is packed into a graph model class so that:
class AbstractGraph
{
virtual QList<AbstractNode*> nodes() const = 0;
virtual QList<AbstractEdge*> edges() const = 0;
};
class GraphModel : public AbstractGraph
{
public:
virtual QList<AbstractNode*> nodes() const override; //this converts m_Nodes to a list of AbstractNode*
virtual QList<AbstractEdge*> edges() const override; //dtto
private:
QList<Node*> m_Nodes;
QList<Edge*> m_Edge;
};
The reason for this convoluted structure is that there are different classes implementing AbstractGraph such as sorting models, filtering and those come in different variants - some store their data just as the model shown and have their own sets of AbstractItem/Node/Edge derived classes, others are dynamic and rely on the data of underlying graph/model without data of their own. Example:
class FilterNode : public AbstractNode
{
//access the data in the m_Item via AbstractItem interface and implements differently AbstractNode interface
private:
AbstractItem *m_Item = nullptr; //this variable holds pointer to some real item with actual data such as the one from GraphModel
};
class GraphFilter : public AbstractGraph
{
//implements the interface differently to the GraphModel
private:
QList<FilterNode*> m_Nodes;
AbstractGraph *m_Source = nullptr; //source graph...
};
I have second thoughts about this because it relies on (virtual)inheritance, relies on abstract methods called through base etc. Is the overhead from this all that significant?
The alternative would be either:
a) Copy-paste lots of code to avoid virtual methods and most of the inheritance but it would be code maintanance nightmare. Plus no common interfaces...
b) Template it all out somehow... this I am somewhat unsure about and I do not know whether it is even possible. I do use them at few places in this already to avoid code duplication.
So does it seem reasonable or like an overkill? I might add that in some cases I will call the methods directly (inside the models) bypassing the virtual calls but on the outside it will pretty much always called via the abstract base.

Trying to implement generic graph algorithms using dynamic polymorphism with C++ makes things
Unnecessary hard.
Unnecessary slow.
The virtual function overhead stands out more significantly the simpler the functions are. In the quoted interface you also do return containers from various functions. Even if these are COW container, there is some work involved and accessing the sequence casually may easily unshare (i.e., copy) the represetation.
In the somewhat distant past (roughly 1990 to 1996) I have experimented with a dynamic polymorphism based generic implementtion of graph algorithms and was struggling with various problems to make it work. When I read first about STL it turned out that most of the problems can be addressed via a similar abstraction (although one key idea was still missing: property maps; see the reference to BGL below for details).
I found it preferable to implement graph algorithms in terms of an STL-like abstraction. The algorithms are function template implemented in terms of specific concepts which are sort of like base classes except for two key differences:
There are no virtual function calls involved in the abstraction and functions can normally be inlined.
The types returned from functions only need to model an appropriate concept rather than having to be compatible via some form of inheritance to some specific interface.
Admittedly I'm biased because I wrote my diploma thesis on this topic. For an [independently develop] application of this approach have a look at the Boost Graph Library (BGL).
For some performance measurements comparing different function call approaches, have a look at the function call benchmarks. They are modelled after the performance measurements for function calls from the Performance TR.

Related

Is it alright to put data members in an interface?

Recently, I've learnt about composite pattern. I want to use it in my assignment which I have to implement File and Folder classes. I realize that sub-classes like CFile and Cfolder got to have the same attributes (name and size). So is it alright for me to put the attributes into the interface? As far as I know, it is not good practice to do so. However, I don't understand why I shouldn't. Or is there any other solutions?
I would say its not a problem. Th difference is that instead of a pure interface class you have an abstract base class. However, if you want to retain the flexibility to use the interface for implementations that are not tied down to those specific member variables then you can always create an interface class as well as an abstract base class for full flexibility. Though that may be getting overly complex overly soon, you can always split the interface from the abstract base later if you need to.
using CItemUPtr = std::unique_ptr<class CItem>;
/**
* Interface class
*/
class CItem
{
public:
virtual ~CItem() {}
virtual CItemUPtr findByName(std::string const& name) = 0;
virtual void setHidden(bool a, bool b) = 0;
};
/**
* Abstract base class
*/
class AbstractCItem
: public CItem
{
protected:
std::string name;
std::size_t size;
};
class CFile
: public AbstractCItem
{
public:
CItemUPtr findByName(std::string const& name) override
{
// stuff
return {};
}
void setHidden(bool a, bool b) override {}
};
It's not really a question of "is it a good practice". By creating an interface, you're defining a standard. The question is, do you NEED the implementation of the interface to contain those data members? You are in the best position to understand your implementation, so you're really the only one who can answer this.
As a general rule, the class implementing the interface should be a black box, and the outside world shouldn't have access to any internals (including member data). Interfaces define common functionality that is required to be present to be able to support the interface, and I'd expect those implementation details to be buried in the underlying implementation of the class only, as a general rule. YMMV.
The design principle for a class should be:
'It is impossible to break the class invariant from the outside'
If the constructor(s) set up the class invariant, and all members
uphold the class invariant, this is achieved.
However, if the class does not have a class invariant, having
public members achieves the same thing.
// in C++, this is a perfectly fine, first order class
struct Pos
{
int x,y;
Pos& operator+=(const Pos&);
};
also see https://en.wikipedia.org/wiki/Class_invariant

Is it bad programming practice to mix virtual and non-virtual functions in a base class?

I have a base class Base that I declare several polymorphic subclasses of. Some of the base class's functions are pure virtual while others are used directly by the subclass.
(This is all in C++)
So for instance:
class Base
{
protected:
float my_float;
public:
virtual void Function() = 0;
void SetFloat(float value){ my_float = value}
}
class subclass : public Base
{
void Function(){ std::cout<<"Hello, world!"<<std::endl; }
}
class subclass2 : public Base
{
void Function(){ std::cout<<"Hello, mars!"<<std::endl; }
}
So as you can see, the subclasses would rely on the base class for the function that sets "my_float", but would be polymorphic with regards to the other function.
So I'm wondering if this is good practice. If you have an abstract base class, should you make it completely abstract or is it okay to do this sort of hybrid approach?
This is a common practice. In fact, some well-known design patterns rely on this, such as the Template Method Pattern. In a nutshell, this allows you to specify some aspects of the behavior you're describing through your class hierarchy as invariant, while letting other aspects of that behavior vary based on the specific type of instance you are referring to at a given point.
Whether or not it is a good or not depends on your precise use case: does it make sense for you to share the implementation of your float member data storage among all your base classes ? This is a bit hard to answer with the example you posted as the derived classes do not rely on my_float in any way, but there are tons of cases where this makes sense and is a good way to split the responsibilities of your class hierarchy.
Even in cases where it does make sense to share implementation of details across classes, you have several other options, such as using composition to share functionality. Sharing functionality through a base class often allows you to be less verbose compared to sharing this functionality via composition, because it allows you to share both the implementation and the interface. To illustrate, your solution has less duplicated code than this alternative that uses composition:
class DataStorage {
private:
float data_;
public:
DataStorage()
: data_(0.f) {
}
void setFloat(float data) {
data_ = data;
}
};
class NotASubclass1 {
private:
DataStorage data_;
public:
void SetFloat(float value){ data_.setFloat(value); }
...
}
class NotASubclass2 {
private:
DataStorage data_;
public:
void SetFloat(float value){ data_.setFloat(value); }
...
}
Being able to have some functions non-virtual has certain benefits, many strongly related:
you can modify them, knowing invocations via a Base*/Base& will use your modified code regardless of what actual derived type the Base* points to
for example, you can collect performance measurements for all Base*/&s, regardless of their derivation
the Non-Virtual Interface (NVI) approach aims for "best of both worlds" - non-virtual functions call non-public virtual functions, giving you a single place to intercept calls via a Base*/& in Base as well as customisability
calls to the non-virtual functions will likely be faster - if inline, up to around an order of magnitude faster for trivial functions like get/set for few-byte fields
you can ensure invariants for all objects derived from Base, selectively encapsulating some private data and the functions that affect it (the final keyword introduced in C++11 lets you do this further down the hierarchy)
having data/functionality "finalised" in the Base class aids understanding and reasoning about class behaviour, and the factoring makes for more concise code overall, but necessarily at the cost of frustrating flexibility and unforeseen reuse - tune to taste

Derived class from a templated base class

I am quite new to real use of templates, so I have the following design question.
I am designing classes Bunch2d and Bunch4d that derive from a abstract base class Bunch:
class Bunch {virtual void create()=0;};
class Bunch2d : public Bunch {void create();};
class Bunch4d : public Bunch {void create();};
The class Bunch will contain a container, a deque or a vector (see this question: Choice of the most performant container (array)) of Particle's:
typedef Blitz::TinyVector<double,DIMENSIONS> Particle;
You therefore see my question: Bunch has to contain this container, because the "base" operations on my bunch are "dimension independant" (such a "size of the container", "clear container", etc.), so I think that the container belongs to the base class ("Bunch 'has a' container).
But this container has to know the dimensions (2 or 4) of the derived class.
So my idea would be to use a templated base class to give the typedef the correct dimension of the container:
enum Dimensions {TwoDimensions = 2, FourDimensions = 4, SixDimensions = 6};
template<Dimensions D> class Bunch
{
protected:
typedef Blitz::TinyVector<double,D> Particle;
std::deque<Particle> particles_store;
public:
virtual void create() = 0;
virtual ~Bunch();
};
class Bunch2d : public Bunch<TwoDimensions>
{
public:
~Bunch2d();
void create();
};
class Bunch4d : public Bunch<FourDimensions>
{
public:
~Bunch4d();
void create();
};
Can you give me your opinion on this design ? Would it be correct use of templates ? What about the validity of the OO concepts ? With a templated base class ?
Thanks for you help/answer/opinion.
There is one single note: different template instances (ie template classes with different types in the parameters) are of different types, and therefore are NOT a single base class.
If you need polymorphism, you will need to add a layer in your design:
class Bunch
{
public:
virtual void create() = 0;
virtual ~Bunch();
};
template <Dimensions D>
class TBunch: public Bunch
{
private:
typedef Blitz::TinyVector<double,D> Particle;
std::deque<Particle> mParticles;
};
class Bunch2d : public TBunch<TwoDimensions>
{
public:
~Bunch2d();
void create();
};
On another note: protected should be banned for attributes.
The issue is one of coupling, since protected exposes the attributes / methods to an unknown number of classes, it's no different than public in that it's impossible to reliably state how many methods will be affected by a change of implementation.
For methods, it's acceptable, because methods can be kept backward compatible (sometimes at the cost of some tricks / etc... but still).
For attributes, it's just unacceptable because an attribute is an implementation detail, not an interface, and a change cannot be made backward compatible.
Therefore I urge you not to EVER use protected for an attribute. In this particular case, it would be a good idea to factor the accesses to mParticles in the template class, without exposing the underlying implementation.
Small hint: if you cannot switch between deque and vector without breaking something beyond the class that holds them, then you have a design issue.
You'd then loose the ability to have a pointer of Bunch class pointing to either Bunch2d or Bunch4d objects at runtime, and manipulate those objects polymorphically through that pointer. If it's important to you not to loose that, don't make the base class templated. Otherwise there is no point in having virtual functions and abstract base class here at all, so then I'd recommend going just with the template.
For a start, Bunch<TwoDimensions> and Bunch<FourDimensions> are completely unrelated classes, so far as inheritance is concerned. Therefore, Bunch2d and Bunch4d have no common base class!
If this is going to be a problem for you, you'll have to do away with the templating, and have DIMENSIONS parameterised at run-time.

Private method in a C++ interface?

Why would I want to define a C++ interface that contains private methods?
Even in the case where the methods in the public scope will technically suppose to act like template methods that use the private methods upon the interface implementation, even so, we're telling the technical specs. right from the interface.
Isn't this a deviation from the original usage of an interface, ie a public contract between the outside and the interior?
You could also define a friend class, which will make use of some private methods from our class, and so force implementation through the interface. This could be an argument.
What other arguments are for defining a private methods within an interface in C++?
The common OO view is that an interface establishes a single contract that defines how objects that conform to that interface are used and how they behave. The NVI idiom or pattern, I never know when one becomes the other, proposes a change in that mentality by dividing the interface into two separate contracts:
how the interface is to be used
what deriving classes must offer
This is in some sense particular to C++ (in fact to any language with multiple inheritance), where the interface can in fact contain code that adapts from the outer interface --how users see me-- and the inner interface --how I am implemented.
This can be useful in different cases, first when the behavior is common but can be parametrized in only specific ways, with a common algorithm skeleton. Then the algorithm can be implemented in the base class and the extension points in derived elements. In languages without multiple inheritance this has to be implemented by splitting into a class that implements the algorithm based in some parameters that comply with a different 'private' interface. I am using here 'private' in the sense that only your class will use that interface.
The second common usage is that by using the NVI idiom, it is simple to instrument the code by only modifying at the base level:
class Base {
public:
void foo() {
foo_impl();
}
private:
virtual void foo_impl() = 0;
};
The extra cost of having to write the dispatcher foo() { foo_impl(); } is rather small and it allows you to later add a locking mechanism if you convert the code into a multithreaded application, add logging to each call, or a timer to verify how much different implementations take in each function... Since the actual method that is implemented in derived classes is private at this level, you are guaranteed that all polymorphic calls can be instrumented at a single point: the base (this does not block extending classes from making foo_impl public thought)
void Base::foo() {
scoped_log log( "calling foo" ); // we can add traces
lock l(mutex); // thread safety
foo_impl();
}
If the virtual methods were public, then you could not intercept all calls to the methods and would have to add that logging and thread safety to all the derived classes that implement the interface.
You can declare a private virtual method whose purpose is to be derivated. Example :
class CharacterDrawer {
public:
virtual ~CharacterDrawer() = 0;
// draws the character after calling getPosition(), getAnimation(), etc.
void draw(GraphicsContext&);
// other methods
void setLightPosition(const Vector&);
enum Animation {
...
};
private:
virtual Vector getPosition() = 0;
virtual Quaternion getRotation() = 0;
virtual Animation getAnimation() = 0;
virtual float getAnimationPercent() = 0;
};
This object can provide drawing utility for a character, but has to be derivated by an object which provides movement, animation handling, etc.
The advantage of doing like this instead of provinding "setPosition", "setAnimation", etc. is that you don't have to "push" the value at each frame, instead you "pull" it.
I think this can be considered as an interface since these methods have nothing to do with actual implementation of all the drawing-related stuff.
Why would I want to define a C++
interface that contains private
methods?
The question is a bit ambiguous/contradictory: if you define (purely) an interface, that means you define the public access of anything that connects to it. In that sense, you do not define an interface that contains private methods.
I think your question comes from confusing an abstract base class with an interface (please correct me if I'm wrong).
An abstract base class can be a partial (or even complete) functionality implementation, that has at least an abstract member. In this case, it makes as much sense to have private members as it makes for any other class.
In practice it is rarely needed to have pure virtual base classes with no implementation at all (i.e. base classes that only define a list of pure virtual functions and nothing else). One case where that is required is COM/DCOM/XPCOM programming (and there are others). In most cases though it makes sense to add some private implementation to your abstract base class.
In a template method implementation, it can be used to add a specialization constraint: you can't call the virtual method of the base class from the derived class (otherwise, the method would be declared as protected in the base class):
class Base
{
private:
virtual void V() { /*some logic here, not accessible directly from Derived*/}
};
class Derived: public Base
{
private:
virtual void V()
{
Base::V(); // Not allowed: Base::V is not visible from Derived
}
};

Implementing complex inheritance in C++

I have the following existing classes:
class Gaussian {
public:
virtual Vector get_mean() = 0;
virtual Matrix get_covariance() = 0;
virtual double calculate_likelihood(Vector &data) = 0;
};
class Diagonal_Gaussian : public Gaussian {
public:
virtual Vector get_mean();
virtual Matrix get_covariance();
virtual double calculate_likelihood(Vector &data);
private:
Vector m_mean;
Vector m_covariance;
};
class FullCov_Gaussian : public Gaussian {
public:
virtual Vector get_mean();
virtual Matrix get_covariance();
virtual double calculate_likelihood(Vector &data);
private:
Vector m_mean;
Matrix m_covariance;
};
As you see, the class Gaussian acts as an interface but doesn't have any implementation. This is all working fine.
Now I want to make an class "AdaptedGaussian" where the data vector provided to the calculated_likelihood will be changed before the likelihood is calculated.
Some requirements:
The AdaptedGaussian must be a child-class of Gaussian
AdaptedGaussian must be able to "wrap" or "be an instance of" every possible Gaussian class
AdaptedGaussian must be constructed from an already existing Gaussian Object
The idea I have now is:
class Adapted_Gaussian : public Gaussian {
private:
Gaussian* m_g;
public:
virtual Vector get_mean() { return m_g->get_mean(); }
virtual Matrix get_covariance() { return m_g->get_covariance(); }
virtual double calculate_likelihood(Vector &data)
{
//do something with data
return g->calculate_likelihood(Vector &data);
}
}
There are maybe some disadvantages:
For every method (and there are more than showed here) a dummy method must be written in the new class
If Gaussian is ever extended, and this class would be forgotten, nasty bugs can appear.
Am I doing this in the right way? Or are there better methods to implement this?
Is there maybe a good way to standard delegate every non-implemented method to the same named method of m_g?
Looks good, I think this is a pretty classic implementation of the Adapter pattern. Just don't forget to declare a virtual destructor for your Gaussian class. As for the disadvantages.
The way Java class library deal with the dummy method problem is to create a dummy class that provides empty implementation for every single method. All classes that do not want to implement every single method can just inherit from this dummy class and selectively override methods that interests them.
If you extend your Gaussian class with few more methods, as long as you declare them as pure virtual method you will get a compiler error in your child class file anyway.
As you point out writing a lot of basic pass-through functions is tedious and adds an implied maintenance overhead. Also, having a pointer member implies extra (albeit simple) lifetime management issues of the owned pointer. Probably the simplest way to address these issues is to make AdaptedGaussian a template, templated on the specific instance of Gaussian to be adapted.
template<class BaseGaussian> class AdaptedGaussian : public BaseGaussian
{
virtual double calculate_likelihood(Vector &data)
{
// do something with data
return BaseGaussian::calculate_likelihood(Vector &data);
}
};
This does rely on all adapted instances of Gaussian being default constructible, or at least conforming to a common constructor signature.
If you want to construct an AdaptedGaussian from an existing XXXGaussian, then so long as the XXXGaussian is itself copyable you can add a suitable constructor:
template<class BaseGaussian> class AdaptedGaussian : public BaseGaussian
{
public:
AdaptedGaussian(const BaseGaussian& other) : BaseGaussian(other)
{
}
// ...
};
This could maybe also be solved by a Strategy Pattern.
It seams to me, that duffymo also was thinking in this direction with "composition". Change the design in that way, that the base class calls some method of an other object it contains. This object contains the coding for calculate_likelihood. Either the whole method can be deferred or only the modifications (in the second case, the default would be to just do nothing).
E.g.: (corrected version)
class Gaussian {
private:
Cl_Strategy* m_cl_strategy;
public:
Gaussian(Cl_Strategy* cl_strategy) {
m_cl_strategy = cl_strategy;
};
virtual Vector get_mean() = 0;
virtual Matrix get_covariance() = 0;
virtual double _calc_likelihood(Vector &data) = 0;
virtual double calculate_likelihood(Vector &data) {
m_cl_strategy->do_your_worst(this, data);
return _calc_likelihood(data);
};
};
I hope, I got that one right, my C++ is a little bit dusted ...
_calc_likelihood must be implemented by subclasses and calculate_likelihood binds all together.
Of course, this solution adds a little overhead, but in some situations, the overhead might be OK.
In Java, it's common to have both an interface and an abstract class that implements it to provide default behavior for all methods. (See Joshua Bloch's design of the Collections API in java.util package.) Perhaps that can help you here as well. You'll give clients a choice of using either the interface or the abstract class.
You can also try composition. Pass an instance of an adapted Gaussian to subclasses and defer behavior to it.