C++ inheritance, base functions still being called when overriden - c++

I have the following two classes, one inherits from the other
Class A{
void print(){cout << "A" << endl;}
}
Class B : A{
void print(){cout << "B" << endl;}
}
Class C : A{
void print(){cout << "C" << endl;}
}
Then in another class I have the following:
vector<A> things;
if (..)
things.push_back(C());
else if (..)
things.push_back(B());
things[0].print();
this always prints A
I'd like it to print B or C depending on which thing I've added to the vector
how do I do this?
I've tried abstraction but I'm not entirely sure how to use it in C++ and it hasn't been working for me

As mentioned, you need virtual functions to enable polymorphic behaviour and can't store classes directly by value in the vector.
When you use a std::vector<A>, you are storing by value and thus objects that you add, e.g. via push_back() are copied to an instance of an A, which means you lose the derived part of the objects. This problem is known as object slicing.
As already suggested you can avoid that by storing pointers (or smart pointers) to the base class, so only pointers are copied into the vector:
std::vector<A*> things;
things.push_back(new B());
// ... use things:
things[0]->print();
// clean up later if you don't use smart pointers:
for(std::vector<A*>::iterator it = things.begin(); it != things.end(); ++it)
delete *it;

1) You need to declare print() as virtual in class A.
2) Your vector is incorrect -- you can't store actual class A objects in there; you will need to store pointers to them for the correct behavior (and you will have to clean up after them later) and/or use something like a boost::shared_ptr.

You need to declare the function virtual in your base class, in this case that's class a:
class A{
virtual void print(){cout << "A" << endl;}
}
The other classes will pick this up even if you don't write virtual in those (but you can).
Virtual tells the compiler that the function could be overridden. When you don't use virtual, it's called hiding and works differently, as you've found.

Related

C++ method overriding when using parent type

Heyo, I'm a little confused about how method overriding works when you involve calling objects as their parent type.
Here is my example code:
#include <iostream>
#include <cstdlib>
#include <vector>
using namespace std;
class A {
public:
A() {
std::cout << "Made A.\n";
}
void doThing() {
std::cout << "A did a thing.\n";
};
};
class B : public A {
public:
B() {
std::cout << "Made B.\n";
}
void doThing() {
std::cout << "B did a thing.\n";
};
};
class C : public A {
public:
C() {
std::cout << "Made C.\n";
}
void doThing() {
std::cout << "C did a thing.\n";
};
};
int main(int argc, char** argv) {
std::cout << "\n";
std::cout << "Make objects: \n";
A a;
B b;
C c;
std::cout << "Call objects normally: \n";
a.doThing();
b.doThing();
c.doThing();
std::cout << "Call objects as their parent type from a vector: \n";
vector<A> vect;
vect.push_back(a); vect.push_back(b); vect.push_back(c);
for(int i=0;i<vect.size();i++)
vect.data()[i].doThing();
return 0;
}
And here is the output I get:
Make objects:
Made A.
Made A.
Made B.
Made A.
Made C.
Call objects normally:
A did a thing.
B did a thing.
C did a thing.
Call objects as their parent type from a vector:
A did a thing.
A did a thing.
A did a thing.
This same code in another language (like Java) would produce this output:
Make objects:
Made A.
Made B.
Made C.
Call objects normally:
A did a thing.
B did a thing.
C did a thing.
Call objects as their parent type from a vector:
A did a thing.
B did a thing.
C did a thing.
In short, how do I achieve that second output in c++?
Whenever you pass a Derived object by value to a function taking a Base, something called "slicing" happens. Basically, only the Base part of the Derived object is being used.
You need to pass the object by reference or by pointer to avoid these issues. For example, declaring
f(Base&)
allows passing in a Derived object, i.e. allows you to write
f(Derived)
In addition, to enable run-time polymorphism, your function must be marked virtual. Java by default has everything implicitly marked virtual. However, this is C++ and you don't pay for what you don't use (virtual functions are an overhead).
PS: in your code, even if you want, you cannot use a std::vector of references. However, you can wrap the objects using std::reference_wrapper which allows you to "simulate" a std::vector of references:
std::vector<std::reference_wrapper<A>> vect
and use the get member function to retrieve the reference
for(int i=0;i<vect.size();i++)
vect[i].get().doThing();
Or, perhaps simpler, just use a std::vector<A*>
You need to use the virtual keyword to enable functions to be overwritten in subclasses.
Ok So here is what's happening:
Make objects:
A is quite obvious I think. The A object gets constructed and its default constructor prints
Made A
When you instantiate a B object first its parent class gets constructed fully. So in this case the parent class is A it gets constructed with the default constructor, which prints out
Made A
After that the B class remaining part gets constructed and runs its constructor which prints out
Made B
The same thing happens when instantiating C
Calling functions on the objects:
Its just a simple function call and since you overwrite the function in each class they get called and not the parent's function.
When you create a vector of the objects you copy the objects into them since you dont pass the reference nor the pointer. You have not written a copy constructor so the default bit by bit copy will run. This way from a B class object you get an A class object which function will print out A did thing and not B did thing. Same happens with C.

free function and inheritance

I am trying a basic thing with two classes and a free functions. First I have two classes :
struct BASE{
BASE(int a = 0):a_(a){};
virtual ~BASE(){};
virtual void foo(){std::cout << "BASE " << std::endl;}
int a_;
};
struct DERIVED: public BASE{
DERIVED():BASE(){};
void foo(){std::cout << "DERIVED " << std::endl;}
};
then I fill up a std::vector (or boost::ptr_vector)
std::vector<BASE* > vec;
vec.push_back( new BASE(2));
vec.push_back( new DERIVED);
If I call my function foo, no pb the virtual stuff works well,
but if I create two free functions :
void foo(BASE* a, DERIVED* b){
std::cout << " mix base/derived " << std::endl;
}
void foo(BASE* a, BASE* b){
std::cout << " full base " << std::endl;
}
if I do
foo(vec[0], vec[1]); //failed
I will get the message
full base
Well it is logical because I have vector of BASE*, but does it exist anyway
to get the good call to my free function ? I need the inheritance so I can not really separate the 2 classes because I must fill up this container
Moreover at the end my vector will be fill up randomly, so I can not know by advance how cast properly.
The simplest (and quickest) way to get workaround is to introduce one more virtual function to unique identify derived classes (using int, enum values or typeid). So later you may call it and realize what exact derived class (or maybe base) you've got behind the BASE*, and do dynamic_cast to that type.
You gave no details about what problem you are trying to solve... just make sure that you've done a complete reaseach for existed solutions if you want to implement a Double Dispatch (or some kind of)...
But usually, if you need dynamic_cast it means that smth wrong with you design (OOP model of domain)...
Just as you don't know in advance what your vec[i] is, so doesn't the compiler. Function overload resolution is a compile time process, while polymorphism - run time.
Thus it calls the void foo(BASE* a, BASE* b) version.
In other words, what you want to do is impossible, unless you use dynamic_cast to try to cast to every possible derived class. It will return 0 if the object is of wrong type.
However, many people will argue that use of dynamic_cast is indication of bad design. And it's expensive as well.
You need dynamic dispatching for that, something like this:
void foo(BASE *a, BASE *b) {
if (DERIVED *bb = dynamic_cast<DERIVED*>(b)) {
foo(a, bb);
} else {
std::cout << " full base " << std::endl;
}
}
If you don't want to use a dynamic_cast, you could add a virtual function to BASE which would return some form of class identifier (e.g. an enum), override this in each derived class and then fork the call based on the return value of this function (along with static_cast).

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.

call a childs version of a function instead of a parents?

Okay, so I got two classes.
class a{
public:
a(){};
void print(){cout << "hello"};
}
class b : public a{
public:
void print(){cout << "hello world";}
}
And a array of parents with a child
a blah[10];
blah[5] = b();
Than I call print, and want it to say hello world.
blah[5].print();
But it calls the parent. How do I fix this?
This can be fixed by declaring the function virtual, a la:
class a{
public:
virtual void print(){
cout << "hello";
}
}
class b : public a{
public:
virtual void print() {
cout << "hello world";
}
}
This is how one implements polymorphism in C++. More here: http://en.wikipedia.org/wiki/Virtual_function
However, it should be noted that in your example, it will never call the child function, because you are using object values, not pointers/references to objects. To remedy this,
a * blah[10];
blah[5] = new b();
Then:
blah[5]->print();
What you're looking for is run-time polymorphism, which means to have the object take "many forms" (i.e. a or b), and act accordingly, as the program runs. In C++, you do this by making the function virtual in the base class a:
virtual void print() {cout << "hello"};
Then, you need to store the elements by pointer or reference, and - as in general the derived classes can introduce new data members and need more storage - it's normal to create the objects on the heap with new:
a* blah[10];
blah[5] = new b();
Then you can call:
blah[5]->print();
And it will call the b implementation of print().
You should later delete blah[5] (and any other's you've pointed at memory returned by new).
In practice, it's a good idea to use a container that can delete the objects it contains when it is itself destructed, whether due to leaving scope or being deleted. std::vector<> is one such container. You can also use smart-pointers to automate the deletion of the a and b objects. This helps make the code correct if exceptions are thrown before your delete statements execute, and you want your program to keep running without leaking memory. The boost library is the easiest/best place to get a smart pointer implementation from. Together:
#include <vector>
#include <boost/shared_ptr.hpp>
std::vector<boost::shared_pointer<a> > blah(10);
blah[5] = new b();
(It's more normal to use vectors with push_back(), as it automatically grows the vector to fit in all the elements you've added, with the new total available by calling vector::size().)
It does that because you told the compiler that your instance was of type a. It's in an array of a objects, right? So it's of type a!
Of course, you want the method in b to overwrite the one in a, despite having a reference of the parent type. You can get that behaviour using the virutal keyword on function declaration in the parent class.
virtual void print(){cout << "hello"};
Why does it work like that?
Because when you cast your object to the parent class, you introduced an ambiguity. When this object's print() is called, how should we treat it? It is of type b, but the reference is of type a, so the sorrounding code may expect it to behave like a, not b!
To disambiguate, the virtual keyword is introduced. virtual functions are always overridden, if the object is of a child class containing a method with the same signature.
Cheers!
Declare a::print() as virtual and use pointer/reference to call the print() function. When you do blah[5] = b(), it does object slicing. You don't have any effect calling a virtual function using object.