Reputation: 177
What do people here use C++ Abstract Base Class constructors for in the field? I am talking about pure interface classes having no data members and no non-pure virtual members.
Can anyone demonstrate any idioms which use ABC constructors in a useful way? Or is it just intrinsic to the nature of using ABCs to implement interfaces that they remain empty, inline and protected?
Upvotes: 0
Views: 1753
Reputation: 507313
I can't think of many useful examples. A class without data-members has no state and thus can't initialize anything. You can have the constructor/destructor do logging for you, though. For example, to log the creation/destruction of all Visitor objects:
class Visitor {
public:
Visitor() {
std::cout << "Visitor@" << this << " created"
<< std::endl;
}
virtual ~Visitor() {
std::cout << "Visitor@" << this << " destroyed"
<< std::endl;
}
virtual void visitA(A*) = 0;
virtual void visitB(B*) = 0;
// ...
};
Upvotes: 1
Reputation: 56123
Can anyone demonstrate any idioms which use ABC constructors in a useful way?
Here's an example, although it's a contrived, uncommon example.
You might use it to keep a list of all instances:
class IFoo
{
private:
//static members to keep a list of all constructed instances
typedef std::set<IFoo*> Set;
static Set s_set;
protected:
//new instance being created
IFoo()
{
s_set.insert(this);
}
public:
//instance being destroyed
virtual ~IFoo()
{
s_set.remove(this);
}
... plus some other static method and/or property
which accesses the set of all instances ...
};
Or is it just intrinsic to the nature of using ABCs to implement interfaces that they remain empty, inline and protected?
More usually they're just not declared at all! There's no reason to declare them:
Upvotes: 5
Reputation: 27268
Suppose that there is some behavior that is common for all the derived classes. Such as registering itself in some external registry, or checking validity of something.
All this common code can be placed in base class's constructor, and it will be called implicitly from the constructors of each of the derived classes.
Upvotes: 3
Reputation: 5880
Remember: "Resource acquisition is initialization".
Sometimes we use abstract base classes as some kind of locking mechanism. For example, in a multi-threaded environment, where several threads need to share a single resource, then a thread can use the constructor as a way to acquire the resource, and the destructor to release the resource
void PlayWithPaintBallGun(Target &target)
{
PaintBallGun paintBallGun; // constructor waits until the gun is free,
// then picks it up.
paintBallGun.Aim(target); // Shoot something
paintBallGun.Fire(); //
// Clever! The destructor is automatically
// called when it goes out of scope. So we
// can't forget to put the gun down.
}
Hugo
Upvotes: 1
Reputation: 51316
How could an abstract base class's constructor be used for anything?
Suppose you have an abstract base class B and a derived class D. When an object of type D is created, B's constructor is called first, but at that point, the object "is" still of type B (see here) -- in particular, calling any virtual functions from the body of B's constructor will call B's own implementations of those functions. But if B is a pure abstract class, none of those virtual functions are defined, so the program will crash immediately.
I'm guessing that you intended for B's constructor to call down to the most-derived-class's (e.g. D's) implementation of a virtual function, right? That would be a bad idea in general because D's object is not fully constructed yet, so any accesses to member variables in D from inside D's implementation of the virtual function would access uninitialised memory.
Upvotes: 1