C++ Automatic instantiation of derived classes - c++

I have an abstract base class called Base that other programmers are to write implementations for. In some other part of the application, I want to catch all implementations that have been written and construct a single instance of each. If this could be done with no additional instructions to others beyond "implement Base", that would be beautiful. However, the code I have below, requires that each implementation register itself. It also doesn't work.
#include <iostream>
#include <vector>
class Base;
std::vector<Base*>* registrationList = new std::vector<Base*>;
class Base {
public:
Base(){}
virtual void execute() = 0;
};
class ImplementationOne: public Base {
public:
ImplementationOne(){registrationList->push_back(this);}
void execute(){std::cout << "Implementation One." << std::endl;}
static int ID;
};
class ImplementationTwo: public Base {
public:
ImplementationTwo(){registrationList->push_back(this);}
void execute(){std::cout << "Implementation Two." << std::endl;}
static int ID;
};
int main(int argc, const char * argv[]){
std::cout << "Registration List size: " << registrationList->size() << std::endl;
for(auto it = registrationList->begin() ; it != registrationList->end() ; ++it){
(dynamic_cast<Base*>(*it))->execute();
}
return 0;
}
I get an output of: Registration List size: 0, so it is clear that the implementations were never instantiated. It is probably obvious that this wouldn't happen, but I am a beginner and this is the best I could come up with. I assumed that static int ID; would force instantiation of each implementation, which would then register themselves. I can see static does not result in instantiation. I leave it in my code here since it shows my intent.
What can I do to get automatic instantiation of each implementation? Is it possible?

Adding static members does not cause an instance to be generated, it merely declares that this type has a "global" variable. You never actually defined these members though, so if you tried to use them for anything you would have had a linker error. You'll have to actually instantiate an object and register that.
One solution might be to simply require each derived type to register an instance at startup. This is actually quite easily done, as I show here. (Note I moved your global to a static local of a static function. This prevents several problems you haven't run into yet, including providing an "owner" for the global.)
Unrelated to your issue, your code has problems:
There is almost never any reason to have a pointer to a container.
You are deriving polymorphically from a type with no virtual destructor.
You dynamic_cast<Base*> for no apperent reason.
Each of your derived classes declares but does not define a ID member.

Of course the vector is empty, you never add anything to the it. The constructors of the derived classes are not called since you never create any object instances of them.
Just because you have static members doesn't mean any object instances will be created. It just guarantees that value will be the same between different instances.
You have to explicitly create instances of the classes to have the constructor being called.

Related

Can a derived class be smaller than its parent class?

I'm asking this about C++ since I'm familiar with that but the question really explains itself: is there a language in which we can derive a class and make it occupy less space in memory than the original class?
This question is more of a gimmick than an actual problem I'm trying to solve, but I could imagine that some really high-performant code could benefit from this kind of memory optimization:
Suppose we have:
class Person {
std::string name;
unsigned int age;
}
class PersonNamedJared {
}
In theory, we don't need a field "name" in this subclass since it'll always be "Jared", which could allow for better memory efficiency.
Is the only way to make this happen by replacing the 'name' field in Person with a get_name() function that we simply override in PersonNamedJared to always return "Jared"? How would we still make the name variable in the base class?
I know this example is really bad practice, but it's the best I could come up with. I think there are legitimate reasons to implement this kind of pattern.
Can a derived class be smaller than its parent class?
No. A derived class always contains a base class sub object. An object can never be smaller than its sub objects, so a derived class can never be smaller than its base.
Is the only way to make this happen by replacing the 'name' field in Person with a get_name() function that we simply override in PersonNamedJared to always return "Jared"?
That would be one way to achieve it.
How would we still make the name variable in the base class?
You couldn't have a member variable in a base that you don't want to be in the derived class.
You could for example use multiple inheritance so that you do have a base with the variable in some derived classes. Something like this:
struct Person {
unsigned int age;
virtual std::string name() = 0;
...
struct Named {
std::string name;
};
struct NamedPerson : Person, private Named {
std::string name() override {
return name;
}
};
struct JaredPerson : Person {
std::string name() override {
return "Jared";
}
};
Here, there is a base with the variable, but Jared does not inherit that particular base.
No.
Inheriting from a class means that you include all its member variables, it's parent class[s] member variables, plus whatever your own class contains.
To put it another way, child classes are a superset of parent classes. (with the exception of an empty child class)
Even private members are still there taking up space, it's just a compiler error to try and access them.
Can a derived class be smaller than its parent class?
In C++, No!
Even if you try to replace a member of the base class with a smaller member in the derived class (by using the same name), the base class member is still there (it's just harder to access). This code will demonstrate that, with the derived class actually adding to the size of the base:
#include <iostream>
class A {
public:
double q[200];
};
class B : A {
public:
double q[100]; // Can we replace base array with a smaller one?
};
int main()
{
std::cout << sizeof(A) << std::endl; // -> 1600 = 200 * sizeof(double)
std::cout << sizeof(B) << std::endl; // -> 2400 ADDS 100 more doubles!
return 0;
}
The answer should be clear if you make use of polymorphism. That is, take advantage of the language features that let you view an object of a derived type as one of a base type. Assume Person is a public base of PersonNamedJared and consider the following code.
PersonNamedJared Jared;
Person * Pointer = &Jared;
std::cout << Pointer->name << " is " << Pointer->age << " years old.";
This is valid, but how could this code possibly work if PersonNamedJared lacked a name field?
As a rule of thumb, if you have a legitimate reason to want a derived class to be smaller than its base class, then there is probably something wrong with your class design.
With regards to could there be a language that has this feature, I think it is possible, but rather awkward. You could – in a hypothetical language – blur the line between data members and function members by allowing the identifier name to represent (virtual) data in the base class but a function in derived classes. So a derived class could provide a function called name, overriding the base class version. You could block explicit references to the base class version of name when dealing with an object of derived type. With enough requirements and prohibitions, the name field would inaccessible in certain derived class objects, hence it would not be needed by them. In that case, the name field could be omitted. (However, I am not aware of any language that permits this stringent setup.)
On the other hand, this setup feels like it runs counter to the principles of inheritance. Even if a language allowed this setup, I would prefer better class design.

Calling a virtual function from within an inherited function?

I've tried to map it out in my head, but honestly I have no idea what's really going on here.
What exactly is happening when I add and remove the virtual keyword from the below example?
#include <iostream>
#include <string>
class A {
public:
A() { me = "From A"; }
void caller() { func(); }
virtual void func() { std::cout << me << std::endl; } // THIS LINE!
private:
std::string me;
};
class B : public A {
public:
B() { me = "From B"; }
void func() { std::cout << me << std::endl; }
private:
std::string me;
};
int main() {
A a;
a.caller();
B b;
b.caller();
return 0;
}
With the virtual keyword, it prints "From A", then "From B".
Without the virtual keyword, it prints "From A", then "From A".
So far, this is the only time I've found a use for virtual functions without pointers being involved. I thought that if the virtual keyword was removed, the compiler would do the standard thing which is to overload the inherited function and end up printing "From A", and "From B" anyway.
I think this is deeper than just the VTable, and that it's more about the way it behaves in particular circumstances. Does B even have a VTable?
The call
func()
is equivalent to
this->func()
so there is a pointer involved.
Still, there's no need to involve pointers to understand the behavior.
Even a direct call of e.g. b.func() has to work as if it's a virtual call, when func is virtual in the statically known type. The compiler can optimize it based on knowing the most derived type of b. But that's a different kind of consideration (optimizations can do just about anything).
Apart from the issue of virtual dispatch, what may bring extra confusion, is that you have two mes, one declared in A and another declared in B. These are two distinct objects.
An object of type B has two data members of type std::string; one on its own, and one incorporated into the subobject of type A. The latter one, though, is not immediately available in the methods of type B because its name is eclipsed by the new me introduced in this class (though you may use a qualified name, A::me to refer to it).
Therefore, even though the bodies of A::func and B::func seem identical, the identifier me used in both of them refers to different members.
In your example, you won't see the difference:
With the virtual function, the compiler will generate a call via the VTable and at runtime, each objects will call the right function for their real class.
With the non virtual function, the compiler determines at compile time the right function to call, based on the objects defined class.
Now try the following, to see the virtual function in action:
A *pa = &b; // pointer to an A: valid as b is a B wich is also an A.
pa -> caller(); // guess what will be called if virtual or not.
No need for pointer to experimenting with virtual functions. You can observe the same effect with references as well:
A& ra = b; // create a reference to an A, but could as well be a parameter passed by reference.
ra.caller();
Virtual functions are useful for polymorphism. The idea is that you work with a general object of a class, but you don't know at compile time, if at runtime the object will really be of this class, or if it will not be a more specialiszed object (inheriting from the class).

Accessing a protected member of a superclass-typed member object - an elegant solution

First off, I know I can not do it, and I think it's not a duplicate questions (this and this questions deal with the same problem, but they only want an explanation of why it does not work).
So, I have a similar concept of classes and inheritance and I would, somehow, elegantly, want to do something that's forbidden. Here's a very simple code snippet that reflects what I want to do:
#include <iostream>
class A{
protected:
int var;
std::vector <double> heavyVar;
public:
A() {var=1;}
virtual ~A() {}
virtual void func() {
std::cout << "Default behavior" << this->var << std::endl;
}
// somewhere along the way, heavyVar is filled with a lot of stuff
};
class B: public A{
protected:
A* myA;
public:
B(A &a) : A() {
this->myA = &a;
this->var = this->myA->var;
// copy some simple data, e.g. flags
// but don't copy a heavy vector variable
}
virtual ~B() {}
virtual void func() {
this->myA->func();
std::cout << "This class is a decorator interface only" << std::endl;
}
};
class C: public B{
private:
int lotsOfCalc(const std::vector <double> &hv){
// do some calculations with the vector contents
}
public:
C(A &a) : B(a) {
// the actual decorator
}
virtual ~C() {}
virtual void func() {
B::func(); // base functionality
int heavyCalc = lotsOfCalc(this->myA->heavyVar); // illegal
// here, I actually access a heavy object (not int), and thus
// would not like to copy it
std::cout << "Expanded functionality " << heavyCalc << std::endl;
}
};
int main(void){
A a;
B b(a);
C c(a);
a.func();
b.func();
c.func();
return 0;
}
The reason for doing this is that I'm actually trying to implement a Decorator Pattern (class B has the myA inner variable that I want to decorate), but I would also like to use some of the protected members of class A while doing the "decorated" calculations (in class B and all of it's subclasses). Hence, this example is not a proper example of a decorator (not even a simple one). In the example, I only focused on demonstrating the problematic functionality (what I want to use but I can't). Not even all the classes/interfaces needed to implement a Decorator pattern are used in this example (I don't have an abstract base class interface, inherited by concrete base class instances as well as an abstract decorator intreface, to be used as a superclass for concrete decorators). I only mention Decorators for the context (the reason I want a A* pointer).
In this particular case, I don't see much sense in making (my equivalent of) int var public (or even, writing a publicly accessible getter) for two reasons:
the more obvious one, I do not want the users to actually use the information directly (I have some functions that return the information relevant to and/or written in my protected variables, but not the variable value itself)
the protected variable in my case is much more heavy to copy than an int (it's a 2D std::vector of doubles), and copying it in to the instance of a derived class would be unnecessarily time- and memory-consuming
Right now, I have two different ways of making my code do what I want it to do, but I don't like neither of them, and I'm searching for a C++ concept that was actually intended for doing something of this sort (I can't be the first person to desire this behavior).
What I have so far and why I don't like it:
1. declaring all the (relevant) inherited classes friends to the base class:
class A{
....
friend class B;
friend class C;
};
I don't like this solution because it would force me to modify my base class every time I write a new subclass class, and this is exactly what I'm trying to avoid. (I want to use only the 'A' interface in the main modules of the system.)
2. casting the A* pointer into a pointer of the inherited class and working with that
void B::func(){
B *uglyHack = static_cast<B*>(myA);
std::cout << uglyHack->var + 1 << std::endl;
}
The variable name is pretty suggestive towards my feelings of using this approach, but this is the one I am using right now. Since I designed this classes, I know how to be careful and to use only the stuff that is actually implemented in class A while treating it as a class B. But, if somebody else continues the work on my project, he might not be so familiar with the code. Also, casting a variable pointer in to something that I am very well aware that it is not just feels pure evil to me.
I am trying to keep this projects' code as nice and cleanly designed as possible, so if anybody has any suggestions towards a solution that does not require the modification of a base class every now and then or usage of evil concepts, I would very much appreciate it.
I do believe that you might want to reconsider the design, but a solution to the specific question of how can I access the member? could be:
class A{
protected:
int var;
static int& varAccessor( A& a ) {
return a.var;
}
};
And then in the derived type call the protected accessor passing the member object by reference:
varAccessor( this->myA ) = 5;
Now, if you are thinking on the decorator pattern, I don't think this is the way to go.
The source of the confusion is that most people don't realize that a type has two separate interfaces, the public interface towards users and the virtual interface for implementation providers (i.e. derived types) as in many cases functions are both public and virtual (i.e. the language allows binding of the two semantically different interfaces). In the Decorator pattern you use the base interface to provide an implementation. Inheritance is there so that the derived type can provide the operation for the user by means of some actual work (decoration) and then forwarding the work to the actual object. The inheritance relationship is not there for you to access the implementation object in any way through protected elements, and that in itself is dangerous. If you are passed an object of a derived type that has stricter invariants regarding that protected member (i.e. for objects of type X, var must be an odd number), the approach you are taking would let a decorator (of sorts) break the invariants of that X type that should just be decorated.
I can't find any examples of the decorator pattern being used in this way. It looks like in C++ it's used to decorate and then delegate back to the decoratee's public abstract interface and not accessing non-public members from it.
In fact, I don't see in your example decoration happening. You've just changed the behavior in the child class which indicates to me you just want plain inheritance (consider that if you use your B to decorate another B the effects don't end up chaining like it would in a normal decoration).
I think I found a nice way to do what I want in the inheritance structure I have.
Firstly, in the base class (the one that is a base for all the other classes, as well as abstract base class interface in the Decorator Pattern), I add a friend class declaration only for the first subclass (the one that would be acting as abstract decorator interface):
class A{
....
friend class B;
};
Then, I add protected access functions in the subclass for all the interesting variables in the base class:
class B : public A{
...
protected:
A *myA;
int getAVar() {return myA->var;}
std::vector <double> &getAHeavyVar {return myA->heavyVar;}
};
And finally, I can access just the things I need from all the classes that inherit class B (the ones that would be concrete decorators) in a controlled manner (as opposed to static_cast<>) through the access function without the need to make all the subclasses of B friends of class A:
class C : public B{
....
public:
virtual void func() {
B::func(); // base functionality
int heavyCalc = lotsOfCalc(this->getAHeavyVar); // legal now!
// here, I actually access a heavy object (not int), and thus
// would not like to copy it
std::cout << "Expanded functionality " << heavyCalc << std::endl;
std::cout << "And also the int: " << this->getAVar << std::endl;
// this time, completely legal
}
};
I was also trying to give only certain functions in the class B a friend access (declaring them as friend functions) but that did not work since I would need to declare the functions inside of class B before the friend declaration in class A. Since in this case class B inherits class A, that would give me circular dependency (forward declaration of class B is not enough for using only friend functions, but it works fine for a friend class declaration).

Is it possible to call derived object's virtual method when down-casted from base class?

Given the following class structure:
class Base
{
virtual void outputMessage() { cout << "Base message!"; }
};
class Derived : public Base
{
virtual void outputMessage() { cout << "Derived message!"; }
}
.. and this code snippet:
Base baseObj;
Derived* convertedObj = (Derived*) &baseObj;
convertedObj->outputMessage();
.. the output will be "Base message!".
Is there any way to cast or manipulate the object to make Derived's version of the outputMessage method to be called polymorphically?
Edit: I will attempt to show the reason why I'm after this:
I am writing migration tools that hook into our main system. For this reason, I need to get access to protected member methods, or customise existing virtual methods. The former I can do by defining a derived class and casting objects to it, to call methods statically. What I can't do is change the behaviour for methods which I do not call statically (ie methods that are called elsewhere in the codebase).
I have also tried creating objects of the derived class directly, but this causes issues in other parts of the system due to the manipulation of the objects passed through the constructor.
No, virtual functions operate on the actual types of the object being pointed to, which in your case is just a simple Base.
Actually, with the down-casting, you're entering undefined-behaviour land here. This can blow off like a bomb with multiple inheritance, where the vtable in the derived class isn't at the same offset as the vtable in the base class.
No Standard-compliant solution
What you're trying to do isn't possible using behaviours guaranteed by the C++ Standard.
If you really MUST do this as a short-term measure to assist your migration, don't depend on it in production, and can adequately verify the behaviour, you could experiment as illustrated below.
Discussion of your attempt
What I'm showing is that you're taking the wrong approach: simply casting a pointer-to-base to a pointer-to-derived doesn't alter the object's vtable pointer.
Deriving a plausible hack
Addressing that, the naive approach is to reconstruct the object in place as a derived object ("placement" new), but this doesn't work either - it will reinitialise the base class members.
What you can possibly do is create a non-derived object that has no data members but the same virtual dispatch table entries (i.e. same virtual functions, same accessibility private/protected/public, same order).
More warnings and caveats
It may work (as it does on my Linux box), but use it at your own risk (I suggest not on production systems).
Further warning: this can only intercept virtual dispatch, and virtual functions can sometimes be dispatched statically when the compiler knows the types at compile time.
~/dev cat hack_vtable.cc
// change vtable of existing object to intercept virtual dispatch...
#include <iostream>
struct B
{
virtual void f() { std::cout << "B::f()\n"; }
std::string s_;
};
struct D : B
{
virtual void f() { std::cout << "D::f()\n"; }
};
struct E
{
virtual void f() { std::cout << "E::f()\n"; }
};
int main()
{
B* p = new B();
p->s_ = "hello";
new (p) D(); // WARNING: reconstructs B members
p->f();
std::cout << '\'' << p->s_ << "'\n"; // no longer "hello"
p->s_ = "world";
new (p) E();
p->f(); // correctly calls E::f()
std::cout << '\'' << p->s_ << "'\n"; // still "world"
}
~/dev try hack_vtable
make: `hack_vtable' is up to date.
D::f()
''
E::f()
'world'
Well, even if you're casting your Base object as a Derived one, internally, it's still a Base object: the vftable of your object (the actual map of functions to RAM pointers) is not updated.
I don't think there is any way to do what you want to do and I don't understand why you'd like to do it.
In this question downcast problem in c++ Robs answer should also be the answer to your problem.
Not at least in legal way. To call Derived class function, you need to have Derived object being referred.

What do *you* use C++ ABC constructors for?

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?
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:
Empty and inline => why bother to declare it?
Protected => the ABC probably already has some pure virtual methods and therefore already can't be instantiated except as a subclass.
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.
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.
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
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;
// ...
};
usually its solely to initialise members to sensible values.