How to call a derived class method from a base class method within the constructor of base - c++

I am wondering if it is possible to call a derived class´ function from within a function called by the base constructor (shouldn´t it already be created when the code in the brackets are executed?)
#pragma once
class ClassA
{
public:
ClassA(void);
virtual ~ClassA(void);
void Init();
protected:
short m_a;
short m_b;
virtual void SetNumbers(short s);
};
include "ClassA.h"
#include <iostream>
ClassA::ClassA(void) : m_a(0), m_b(0)
{
Init();
}
ClassA::~ClassA(void)
{
}
void ClassA::SetNumbers(short s)
{
std::cout << "In ClassA::SetNumbers()\n";
m_a = s;
m_b = s;
}
void ClassA::Init()
{
this->SetNumbers(2);
}
#pragma once
#include "ClassA.h"
class ClassB : public ClassA
{
public:
ClassB(void);
virtual ~ClassB(void);
virtual void SetNumbers(short);
int x;
};
#include "ClassB.h"
#include <iostream>
ClassB::ClassB(void)
{
}
ClassB::~ClassB(void)
{
}
void ClassB::SetNumbers(short s)
{
std::cout << "In ClassB::SetNumbers()\n";
m_a = ++s;
m_b = s;
ClassA::SetNumbers(s);
}
Any suggestions how to do it?...
Thank You in advance :)...

No. All parts of B (starting with A, as it's base) are constructed before B's constructor is called. So, by the time SetNumbers is called, no part of B (except for the A part) has been constructed --- and that may include the v-table, so there's no way to know where that call is going to go.
Of course, there is a simple solution to this: Call B::SetNumber() from within B's constructor (That is, after all, the purpose of B's constructor)

You can't do this for the simple logical reason that while the base class is being constructed, the derived class hasn't even begun to be constructed. You can't call a member function on an object that doesn't exist (yet).
In practice, even if you managed to call SetNumbers and assign to the member variables of the derived class before they were initialized they would surely be overwritten when they finally get initialized. I admit it's a bit pointless to reason about this as we would be well outside defined behaivour.

No, sorry. :( It might compile in one or two C++ compilers, but it's not recommended. From the C++ FAQ Lite section 10.7:
[10.7] Should you use the this pointer
in the constructor?
[...snip...]
Here is something that never works:
the {body} of a constructor (or a
function called from the constructor)
cannot get down to a derived class by
calling a virtual member function that
is overridden in the derived class. If
your goal was to get to the overridden
function in the derived class, you
won't get what you want. Note that you
won't get to the override in the
derived class independent of how you
call the virtual member function:
explicitly using the this pointer
(e.g., this->method()), implicitly
using the this pointer (e.g.,
method()), or even calling some other
function that calls the virtual member
function on your this object. The
bottom line is this: even if the
caller is constructing an object of a
derived class, during the constructor
of the base class, your object is not
yet of that derived class. You have
been warned.
NOTE: Emphasis mine.
More details at the link

The only time you can do this is when something is derived from a template that is parameterised by itself:
template<typename T> class base
{
T* down_cast() throw()
{
return static_cast<Derived*>(this);
}
const T* down_cast() const throw()
{
return static_cast<const Derived*>(this);
}
public:
base()
{
down_cast()->doSomething();
}
/* … */
};
class derived : private base<derived>
{
public:
void doSomething()
{
}
};
Note that doSomething is public and not virtual.
We can static_cast to derived, because it's known that derived is the derived type.
Deriving something from a base parameterised by itself is a strange thing to be doing at the best of times. It's said that when the ATL team in microsoft used it they asked the C++ compiler team if it was valid and nobody was sure, though it is valid because template construction depends on names as follows:
First the template is available, but not used in a class. Then, the name derived available. Then it instantiates the layout of base<derived> — this requires knowledge of the member variables and virtual functions, as long as none of that depends upon knowledge of derived’s layout (pointers and references are fine) this will all go okay. Then it will create the layout of derived, and finally it will create derived’s member functions, which may include creating member functions for base<derived>. So as long as base<derived> doesn’t contain a derived member variable (base classes can never contain a member variable of a type derived from themselves) or a virtual function that requires knowledge of derived’s layout we can indeed do the dicey-looking piece of inheritance above.
This includes being able to call non-virtual public members of derived from base during construction, because it's already part of base. There are strong limitations on this. In particular, if doSomething() depends on anything constructed in derived's constructor it won't work as derived hasn't been constructed yet.
Now, is this actually a good idea? No.

A simple design solution is to use aggregation instead of inheritance.

Related

Dynamic binding inside constructor for virtual Function in C++

As per the standard, we know that constructor always go for an early binding of a virtual function inside them because they don't have complete idea the derived class hierarchy downside.
In this case if early binding is used inside my base constructor, I have passed a derived object to a base class pointer which is completely acceptable (an upcasting is done here). If early binding is used the selection of the virtual function should be based on the type of the pointer (which is Base * here) but not the content of the pointer(the object pointed by the pointer because we don't know the exact object being pointed). In that case since the pointer type is Base * we should have invoked only Base class virtual function in both cases. Could some one please clarify this?
I think dynamic binding is used here rather than early binding. Please correct me if my understanding is wrong.
The first line of the output which invokes base is completely fine
class Base
{
public:
Base(){
fun();
}
Base(Base *p)
{
p->fun();
}
virtual void fun()
{
cout<<"In Base"<<endl;
}
};
class Derived : public Base
{
public:
void fun()
{
cout<<"In Derived"<<endl;
}
};
int main()
{
Derived d;
Base b(&d);
}
O/P :
In Base
In Derived
The rule for virtual calls within a constructor body applies to an object currently being constructed, because that object is not yet considered to be an object of any derived class. (And there's a similar rule for an object currently being destroyed.) It has little to do with "early binding" in the sense of using a compile-time type, such as the syntax ClassName::member_func() forces.
Your code has two different objects d and b, and the constructor of d has entirely finished by the time you get to the p->fun(); line.
In detail:
The program enters main.
The object d is created using the implicitly declared default constructor of Derived.
The first thing Derived::Derived() does is create the base class subobject, by calling the default constructor Base::Base().
The body of Base::Base() calls fun(). Since we have not yet entered the body of the Derived::Derived() constructor, this virtual lookup invokes Base::fun().
Base::Base() finishes.
The body of Derived::Derived(), which is empty, executes and finishes.
Back in main, the object b is created by passing a pointer to d to the constructor Base::Base(Base*).
The body of Base::Base(Base *p) calls p->fun(). Since p is a pointer to d, which is already a completely constructed object of type Derived, this virtual lookup invokes Derived::fun().
Contrast with this slightly different example, where we define a default constructor of Derived to pass this (implicitly converted to Base*) to the constructor for the Base subobject. (This is valid, though could be risky if the pointer were used in other ways, such as in an initializer for a base or member of Base.)
#include <iostream>
using std::cout;
using std::endl;
class Base
{
public:
Base(){
fun();
}
Base(Base *p)
{
p->fun();
}
virtual void fun()
{
cout<<"In Base"<<endl;
}
};
class Derived
{
public:
Derived() : Base(this) {}
virtual void fun() override
{
cout << "In Derived" << endl;
}
};
int main()
{
Derived d;
}
This program will print just "In Base", since now in Base::Base(Base *p), p does point at the same object which is currently being constructed.
The reason is that C++ classes are constructed from Base classes to derived classes and virtual call table of the complete object is created when the object creation process is completed. Therefore, the base class function is called in the code excerpt above. Unless otherwise mandatory, you should never make virtual function calls in the constructor. Below is an excerpt from Bjarne Stroustrup's C++ Style and Technique FAQ:
In a constructor, the virtual call mechanism is disabled because
overriding from derived classes hasn’t yet happened. Objects are constructed from the base up, “base before derived”.
Destruction is done “derived class before base class”, so virtual
functions behave as in constructors: Only the local definitions are used –
and no calls are made to overriding functions to avoid touching the (now
destroyed) derived class part of the object.

Calling Derived class method which is private from Base class pointer [duplicate]

I have a Base class pointer pointing to derived class object. The method foo() is public in base class but private in derived class. Base class foo() is virtual. So when i call foo() from Base class pointer, Vptr Table has the address of derived class foo(), BUT its private in Derived class ...so how is it getting called.??
I understand Run time polymorphism and i also understand that the Access specifiers work for compile time and Virtual concept works at run time. So there shall be No Compiler error.
My question is : Is this is a loop hole through which we can call private methods of Derived class ? or Its expected to behave this way.
Any good Explanation for this behavior.
Thanks a lot in advance.
CODE :
class A
{
public:
virtual void foo()
{
std::cout << "In A";
}
};
class B:public A
{
private:
void foo()
{
std::cout << "In B ??? Its Private Method :-( ";
}
};
int main()
{
A* ptr = new B();
ptr->foo();
return 0;
}
It's private method, but since it's virtual - it can be called.
n3690 11.5/1
The access rules (Clause 11) for a virtual function are determined by its declaration and are not affected by
the rules for a function that later overrides it.
Why this? Since
n3690 11.5/2
Access is checked at the call point using the type of the expression used to denote the object for which the
member function is called (B* in the example above). The access of the member function in the class in
which it was defined (D in the example above) is in general not known.
Access level is a compile-time concept. The runtime doesn't know if a method was declared private or public. Those are there for your convenience.
This is actually a good coding standard - a virtual method should be ideally public in the base class and private or protected in derived classes. This will force the caller to use the interfaces rather than the actual types (of course, this isn't always practical, but a good thing to take into account).
The concrete type is abstracted away in your case, as it should be. The base method is declared public and you're calling it through a pointer to a base, so it's allowed.

How do I call a derived class method from the base class constructor in C++? [duplicate]

This question already has answers here:
Calling a virtual function from the constructor
(3 answers)
Closed 8 years ago.
I have a base class and two derived classes. The base class constructor should calculate some properties when it is called, although those properties depend on the derived class details. To avoid recoding the same steps inside each derived class constructor, I code these steps in the base class constructor like in the example below.
The problem is that when I do this, the base class constructor do not call the overridden methods. Instead, it calls its own method. Is there a way to solve that? Although it makes sense as well, what's the reason this behavior happens?
Coming from a C# background, that's very odd, since it would work nicely there. In C#, I would use the keyword base to call any base class method whereas this would always call the derived class methods.
Example:
example.h
#define _USE_MATH_DEFINES
#include <math.h>
class Base
{
public:
Base(void);
~Base(void);
protected:
virtual void Method(void);
};
class Derived : public Base
{
public:
Derived(void);
~Derived(void);
protected:
virtual void Method(void);
};
example.cpp
#include <iostream>
Base::Base()
{
this->Method(); // This calls Base->Method instead of Derived->Method
}
Base::~Base(){}
void Base::Method() // If I remove this, I have an error "externals undefined"
{
std::cout << "called Base->Method()" << endl;
}
Derived::Derived()
: Base()
{
this->Method(); // This obviously calls Derived->Method
}
Derived::~Derived(){}
void Derived::Method()
{
std::cout << "called Derived->Method()" << endl;
}
main.cpp
int main()
{
Base* d = new Derived();
/*
Outputs:
called Base->Method()
called Derived->Method()
*/
}
There is no way to do that, because when the base class constructor is run, the object is not yet an object of the derived type. In particular, data members introduced in the derived class are not initialised until after the base class constructor is run -- in essence, the base class object behaves like a data member of the derived class.
One way or another, you will have to defer the calculation until the derived class's constructor is entered. If I understand what you're trying to do correctly, the best way is probably to give the base class a member function that does the calculations and call that from the derived classes' constructors.
Constructors and destructor are the only places where the virtual functionality doesn't kick in.
Because the Derived object is yet to be constructed and calling Derived function would have resulted in Undefined Behavior. In case of destructor, Derived object is already destructed.
This is explained in Bjarne Stroustrup's Technical FAQ page.
The only way left is to let the object get constructed and then call the Method().

Derived class Private method is getting called

I have a Base class pointer pointing to derived class object. The method foo() is public in base class but private in derived class. Base class foo() is virtual. So when i call foo() from Base class pointer, Vptr Table has the address of derived class foo(), BUT its private in Derived class ...so how is it getting called.??
I understand Run time polymorphism and i also understand that the Access specifiers work for compile time and Virtual concept works at run time. So there shall be No Compiler error.
My question is : Is this is a loop hole through which we can call private methods of Derived class ? or Its expected to behave this way.
Any good Explanation for this behavior.
Thanks a lot in advance.
CODE :
class A
{
public:
virtual void foo()
{
std::cout << "In A";
}
};
class B:public A
{
private:
void foo()
{
std::cout << "In B ??? Its Private Method :-( ";
}
};
int main()
{
A* ptr = new B();
ptr->foo();
return 0;
}
It's private method, but since it's virtual - it can be called.
n3690 11.5/1
The access rules (Clause 11) for a virtual function are determined by its declaration and are not affected by
the rules for a function that later overrides it.
Why this? Since
n3690 11.5/2
Access is checked at the call point using the type of the expression used to denote the object for which the
member function is called (B* in the example above). The access of the member function in the class in
which it was defined (D in the example above) is in general not known.
Access level is a compile-time concept. The runtime doesn't know if a method was declared private or public. Those are there for your convenience.
This is actually a good coding standard - a virtual method should be ideally public in the base class and private or protected in derived classes. This will force the caller to use the interfaces rather than the actual types (of course, this isn't always practical, but a good thing to take into account).
The concrete type is abstracted away in your case, as it should be. The base method is declared public and you're calling it through a pointer to a base, so it's allowed.

Implicit upcasting question

I find when writing functions (that use function overloading) that accept either a main class or subclass argument, that often implicit upcasting will occur (the subclass is upcasted as the main class and the main class function called). I don't want this implicit upcasting to occur as it means subtle bugs sneak in and cause problems later on down the line.
I have searched on google for information on this, but there is little coherent information I can make use of and only indirect references to it.
How do I disable, stop or prevent implicit upcasting (and even downcasting) from occurring?
(I can't supply any example code as this is a general problem that occurs from time to time).
No, this isn't to do with methods (I would have specified methods) but functions.
No example code, but pseudo idea:
void Function(BaseClass &A);
void Function(SubclassClass &B);
Function(ASubclass); //Implicit upcasting occurs, calls BaseClass instead
The above situation won't happen conventionally (say that the SubclassClass function gets knocked out/erased), but Subclass will be upcast to the BaseClass for use with the BaseClass function, instead of, say, reporting an error or generating a warning - either would be helpful as I don't want implicit upcasting to occur.
Please don't confuse upcasting with non-virtual method calls.
class Base
{
};
class Derived1:public Base
{
};
class Derived2:private Base
{
};
void doSomething(Base *ptr)
{
}
int main()
{
Derived1 *ptr1 = new Derived1;
Derived2 *ptr2 = new Derived2;
doSomething(ptr1); //works fine
doSomething(ptr2); //Gives error
return 0;
};
Upcasting:
A Base class pointer can always point to a derived class object as long as the derived class is publically derived from the Base class. Eg: First Function Call.
This upcasting happens implicitly.
If the derivation is private this upcasting does not happen implicitly and compiler will issue an error.
Though, using private inheritance is not the way to achieve this behavior. You should use private inheritance if it suits your design and it will implicitly gaurantee you that upcasting never happens implicitly.
The "up-casting" you are talking about is normal. The symptoms you are describing sound like you are overloading a non-virtual parents member function.
For example
#include <iostream>
using namespace std;
struct A
{
void sayHello() {cout << "hello from A" << endl;}
};
struct B : public A
{
void sayHello() {cout << "hello from B" << endl;}
};
void hello(A& a)
{
a.sayHello();
}
int main()
{
A a;
B b;
hello(a);
hello(b);
}
will produce
hello from A
hello from A
but if you add the virual to A::sayHello everything works as you would expect
struct A
{
virtual void sayHello() {cout << "hello from A" << endl;}
};
I'm not 100% sure what's going on, but if base class methods are being called when you supply a derived-class object to a method with a base-class parameter type, then either a) you didn't override the base-class method in your derived class, or more likely b) you forget the 'virtual' keyword in your base-class declaration. Otherwise the derived-class method will be called as expected.
#Als your example wont work if derivation is in protected mode.Implicit upcasting is allowed within the derived class only (within methods of the derived class) because protected members can only be accessed inside the class that derives or base class.