I have a base class MyBase that contains a pure virtual function:
void PrintStartMessage() = 0
I want each derived class to call it in their constructor
then I put it in base class(MyBase) constructor
class MyBase
{
public:
virtual void PrintStartMessage() =0;
MyBase()
{
PrintStartMessage();
}
};
class Derived:public MyBase
{
public:
void PrintStartMessage(){
}
};
void main()
{
Derived derived;
}
but I get a linker error.
this is error message :
1>------ Build started: Project: s1, Configuration: Debug Win32 ------
1>Compiling...
1>s1.cpp
1>Linking...
1>s1.obj : error LNK2019: unresolved external symbol "public: virtual void __thiscall MyBase::PrintStartMessage(void)" (?PrintStartMessage#MyBase##UAEXXZ) referenced in function "public: __thiscall MyBase::MyBase(void)" (??0MyBase##QAE#XZ)
1>C:\Users\Shmuelian\Documents\Visual Studio 2008\Projects\s1\Debug\s1.exe : fatal error LNK1120: 1 unresolved externals
1>s1 - 2 error(s), 0 warning(s)
I want force to all derived classes to...
A- implement it
B- call it in their constructor
How I must do it?
There are many articles that explain why you should never call virtual functions in constructor and destructor in C++. Take a look here and here for details what happens behind the scene during such calls.
In short, objects are constructed from the base up to the derived. So when you try to call a virtual function from the base class constructor, overriding from derived classes hasn't yet happened because the derived constructors haven't been called yet.
Trying to call a pure abstract method from a derived while that object is still being constructed is unsafe. It's like trying to fill gas into a car but that car is still on the assembly line and the gas tank hasn't been put in yet.
The closest you can get to doing something like that is to fully construct your object first and then calling the method after:
template <typename T>
T construct_and_print()
{
T obj;
obj.PrintStartMessage();
return obj;
}
int main()
{
Derived derived = construct_and_print<Derived>();
}
You can't do it the way you imagine because you cannot call derived virtual functions from within the base class constructor—the object is not yet of the derived type. But you don't need to do this.
Calling PrintStartMessage after MyBase construction
Let's assume that you want to do something like this:
class MyBase {
public:
virtual void PrintStartMessage() = 0;
MyBase() {
printf("Doing MyBase initialization...\n");
PrintStartMessage(); // ⚠ UB: pure virtual function call ⚠
}
};
class Derived : public MyBase {
public:
virtual void PrintStartMessage() { printf("Starting Derived!\n"); }
};
That is, the desired output is:
Doing MyBase initialization...
Starting Derived!
But this is exactly what constructors are for! Just scrap the virtual function and make the constructor of Derived do the job:
class MyBase {
public:
MyBase() { printf("Doing MyBase initialization...\n"); }
};
class Derived : public MyBase {
public:
Derived() { printf("Starting Derived!\n"); }
};
The output is, well, what we would expect:
Doing MyBase initialization...
Starting Derived!
This doesn't enforce the derived classes to explicitly implement the PrintStartMessage functionality though. But on the other hand, think twice whether it is at all necessary, as they otherwise can always provide an empty implementation anyway.
Calling PrintStartMessage before MyBase construction
As said above, if you want to call PrintStartMessage before the Derived has been constructed, you cannot accomplish this because there is no yet a Derived object for PrintStartMessage to be called upon. It would make no sense to require PrintStartMessage to be a non-static member because it would have no access to any of the Derived data members.
A static function with factory function
Alternatively we can make it a static member like so:
class MyBase {
public:
MyBase() {
printf("Doing MyBase initialization...\n");
}
};
class Derived : public MyBase {
public:
static void PrintStartMessage() { printf("Derived specific message.\n"); }
};
A natural question arises of how it will be called?
There are two solution I can see: one is similar to that of #greatwolf, where you have to call it manually. But now, since it is a static member, you can call it before an instance of MyBase has been constructed:
template<class T>
T print_and_construct() {
T::PrintStartMessage();
return T();
}
int main() {
Derived derived = print_and_construct<Derived>();
}
The output will be
Derived specific message.
Doing MyBase initialization...
This approach does force all derived classes to implement PrintStartMessage. Unfortunately it's only true when we construct them with our factory function... which is a huge downside of this solution.
The second solution is to resort to the Curiously Recurring Template Pattern (CRTP). By telling MyBase the complete object type at compile time it can do the call from within the constructor:
template<class T>
class MyBase {
public:
MyBase() {
T::PrintStartMessage();
printf("Doing MyBase initialization...\n");
}
};
class Derived : public MyBase<Derived> {
public:
static void PrintStartMessage() { printf("Derived specific message.\n"); }
};
The output is as expected, without the need of using a dedicated factory function.
Accessing MyBase from within PrintStartMessage with CRTP
While MyBase is being executed, its already OK to access its members. We can make PrintStartMessage be able to access the MyBase that has called it:
template<class T>
class MyBase {
public:
MyBase() {
T::PrintStartMessage(this);
printf("Doing MyBase initialization...\n");
}
};
class Derived : public MyBase<Derived> {
public:
static void PrintStartMessage(MyBase<Derived> *p) {
// We can access p here
printf("Derived specific message.\n");
}
};
The following is also valid and very frequently used, albeit a bit dangerous:
template<class T>
class MyBase {
public:
MyBase() {
static_cast<T*>(this)->PrintStartMessage();
printf("Doing MyBase initialization...\n");
}
};
class Derived : public MyBase<Derived> {
public:
void PrintStartMessage() {
// We can access *this member functions here, but only those from MyBase
// or those of Derived who follow this same restriction. I.e. no
// Derived data members access as they have not yet been constructed.
printf("Derived specific message.\n");
}
};
No templates solution—redesign
Yet another option is to redesign your code a little. IMO this one is actually the preferred solution if you absolutely have to call an overridden PrintStartMessage from within MyBase construction.
This proposal is to separate Derived from MyBase, as follows:
class ICanPrintStartMessage {
public:
virtual ~ICanPrintStartMessage() {}
virtual void PrintStartMessage() = 0;
};
class MyBase {
public:
MyBase(ICanPrintStartMessage *p) : _p(p) {
_p->PrintStartMessage();
printf("Doing MyBase initialization...\n");
}
ICanPrintStartMessage *_p;
};
class Derived : public ICanPrintStartMessage {
public:
virtual void PrintStartMessage() { printf("Starting Derived!!!\n"); }
};
You initialize MyBase as follows:
int main() {
Derived d;
MyBase b(&d);
}
You shouldn't call a virtual function in a constructor. Period. You'll have to find some workaround, like making PrintStartMessage non-virtual and putting the call explicitly in every constructor.
If PrintStartMessage() was not a pure virtual function but a normal virtual function, the compiler would not complain about it. However you would still have to figure out why the derived version of PrintStartMessage() is not being called.
Since the derived class calls the base class's constructor before its own constructor, the derived class behaves like the base class and therefore calls the base class's function.
I know this is an old question, but I came across the same question while working on my program.
If your goal is to reduce code duplication by having the Base class handle the shared initialization code while requiring the Derived classes to specify the code unique to them in a pure virtual method, this is what I decided on.
#include <iostream>
class MyBase
{
public:
virtual void UniqueCode() = 0;
MyBase() {};
void init(MyBase & other)
{
std::cout << "Shared Code before the unique code" << std::endl;
other.UniqueCode();
std::cout << "Shared Code after the unique code" << std::endl << std::endl;
}
};
class FirstDerived : public MyBase
{
public:
FirstDerived() : MyBase() { init(*this); };
void UniqueCode()
{
std::cout << "Code Unique to First Derived Class" << std::endl;
}
private:
using MyBase::init;
};
class SecondDerived : public MyBase
{
public:
SecondDerived() : MyBase() { init(*this); };
void UniqueCode()
{
std::cout << "Code Unique to Second Derived Class" << std::endl;
}
private:
using MyBase::init;
};
int main()
{
FirstDerived first;
SecondDerived second;
}
The output is:
Shared Code before the unique code
Code Unique to First Derived Class
Shared Code after the unique code
Shared Code before the unique code
Code Unique to Second Derived Class
Shared Code after the unique code
Facing the same problem, I imaginated a (not perfect) solution. The idea is to provide a certificate to the base class that the pure virtual init function will be called after the construction.
class A
{
private:
static const int checkValue;
public:
A(int certificate);
A(const A& a);
virtual ~A();
virtual void init() = 0;
public:
template <typename T> static T create();
template <typeneme T> static T* create_p();
template <typename T, typename U1> static T create(const U1& u1);
template <typename T, typename U1> static T* create_p(const U1& u1);
//... all the required possibilities can be generated by prepro loops
};
const int A::checkValue = 159736482; // or any random value
A::A(int certificate)
{
assert(certificate == A::checkValue);
}
A::A(const A& a)
{}
A::~A()
{}
template <typename T>
T A::create()
{
T t(A::checkValue);
t.init();
return t;
}
template <typename T>
T* A::create_p()
{
T* t = new T(A::checkValue);
t->init();
return t;
}
template <typename T, typename U1>
T A::create(const U1& u1)
{
T t(A::checkValue, u1);
t.init();
return t;
}
template <typename T, typename U1>
T* A::create_p(const U1& u1)
{
T* t = new T(A::checkValue, u1);
t->init();
return t;
}
class B : public A
{
public:
B(int certificate);
B(const B& b);
virtual ~B();
virtual void init();
};
B::B(int certificate) :
A(certificate)
{}
B::B(const B& b) :
A(b)
{}
B::~B()
{}
void B::init()
{
std::cout << "call B::init()" << std::endl;
}
class C : public A
{
public:
C(int certificate, double x);
C(const C& c);
virtual ~C();
virtual void init();
private:
double x_;
};
C::C(int certificate, double x) :
A(certificate)
x_(x)
{}
C::C(const C& c) :
A(c)
x_(c.x_)
{}
C::~C()
{}
void C::init()
{
std::cout << "call C::init()" << std::endl;
}
Then, the user of the class can't construct an instance without giving the certificate, but the certificate can only be produced by the creation functions:
B b = create<B>(); // B::init is called
C c = create<C,double>(3.1415926535); // C::init is called
Moreover, the user can't create new classes inheriting from A B or C without implementing the certificate transmission in the constructor. Then, the base class A has the warranty that init will be called after construction.
I can offer a work around / "companion" to your abstract base class using MACROS rather than templates, or staying purely within the "natural" constraints of the language.
Create a base class with an init function e.g.:
class BaseClass
{
public:
BaseClass(){}
virtual ~BaseClass(){}
virtual void virtualInit( const int i=0 )=0;
};
Then, add a macro for a constructor. Note there is no reason to not add multiple constructor definitions here, or have multiple macros to choose from.
#define BASECLASS_INT_CONSTRUCTOR( clazz ) \
clazz( const int i ) \
{ \
virtualInit( i ); \
}
Finally, add the macro to your derivation:
class DervivedClass : public BaseClass
{
public:
DervivedClass();
BASECLASS_INT_CONSTRUCTOR( DervivedClass )
virtual ~DervivedClass();
void virtualInit( const int i=0 )
{
x_=i;
}
int x_;
};
Related
class Base
{
public:
virtual void f()
{
g();
}
virtual void g()
{
cout<<"base";
}
};
class Derived : public Base
{
public:
virtual void f()
{
Base::f();
}
virtual void g()
{
cout<<"derived";
}
};
int main()
{
Base *pBase = new Derived;
pBase->f();
return 0;
}
In this program I have kept both derived and base class functions as virtual. Is it possible call virtual functions of derived class through base class pointer and base class functions are not virtual.
Thanks in advance..
assuming functions in base class are not virtual
This can be achieved via type erasure. But there are caveats.
Your "base" class should decide between the two:
Being a view class (can't be called delete on or created by itself)
Being a resource owning class (implemented similar to 1, but stores a smart pointer).
Here is an example for case 1: https://godbolt.org/z/v5rTv3ac7
template <typename>
struct tag{};
class base
{
public:
base() = delete;
template <typename Derived>
explicit base(tag<Derived> t)
: _vTable(make_v_table(t))
{}
int foo() const { return _vTable.foo(*this); }
protected:
~base() = default;
private:
struct v_table
{
virtual int foo(const base &b) const = 0;
protected:
~v_table() = default;
};
template <typename Derived>
static const v_table& make_v_table(tag<Derived>){
struct : v_table
{
int foo(const base &b) const {
return static_cast<const Derived&>(b).foo();
}
} static const _vTable{};
return _vTable;
}
private:
const v_table& _vTable;
};
class derived : public base
{
public:
explicit derived()
: base(tag<derived>{})
{}
int foo() const { return 815; }
};
// example
#include <iostream>
int main(){
derived d{};
const base& b = d;
std::cout << b.foo() << '\n';
}
Take notice, that you can only take a pointer or a reference (cv-qualified) to a base class. The base class can't be created on its own.
Also tag<T> is needed to call a templated constructor.
DO NOT CALL DERIVED METHODS IN THE BASE CONSTRUCTOR OR DESTRUCTOR
Simple answer is no, if the function you are calling is not virtual. The Compiler would have no Idea that you are trying to call a function from the Derived Class, and won't make and I'm paraphrasing here since I do not know the proper term for,"Won't make proper entries in the Virtual Table".
class Base
{
public:
void f()
{
std::cout<<"Base f() Called\n";
g();
}
virtual void g()
{
std::cout<<"Base g()\n";
}
virtual ~Base(){std::cout<<"Base Destroyed\n";}
};
class Derived : public Base
{
public:
void f()
{
g();
}
virtual void g()
{
std::cout<<"Derived g()\n";
}
~Derived(){std::cout<<"Derived Destroyed\n";}
};
int main()
{
Derived* D1 = new Derived();
Base* B1 = D1;
B1->f();
delete B1;
return 0;
}
Have a look at the following code, I have not declared Base::f() as virtual,calling B1->f() calls the Base Method, but the base method calls a virtual function Base::g() and this allows the "Derived" method be called.
Have a look at this thread or this blogpost to understand Virtual Tables.
(1) and you must ALWAYS declare the destructor of a base class virtual when destroying Derived Object through a Base Pointer, else the resources used by the Derived Object will never get destroyed and it's memory will leak until the program closes.
Don't Take my word as gospel, I am simply passing on knowledge I have acquired from first hand experience, Except for (1), specially if you are not using smart pointers
So shortly the situation is like this
class Base
{
public:
Base() { setZero();}
virtual void setZero() {std::cout << "Set all Base class values to zeros (default) values";}
};
class Derived : public Base
{
public:
Derived () { }
void setZero() override {
Base::setZero();
std::cout << "Set all Derived class values to zeros (default) values";
}
};
setZero is public an is called form different places, also it has some logic, not just assignments, as Base and Derived classes are quite large.
But it's all doesn't work as intended as dynamic binding doesn't work when function is called from the constructor.
I see the solution to duplicate code from setZero to the consructors, but duplication of code is a bad thing. Is there some other solutions?
You might have factory to have "post-call", something like:
template <typename T, typename ... Ts>
T CreateBaseType(Ts&&... args)
{
T t(std::forward<Ts>(args)...);
t.setZero();
return t;
}
TL;DR - two phase construction sucks. Try to make your constructors construct stuff, and not call any virtual methods, or require it in order to function.
If you want initialization to occur after object construction (including vtables), you need to have a separate initialization phase on your objects.
A probably better way to handle this is this:
class Base
{
int x = 0; // notice the =0 here
public:
Base() {} // nothing
virtual setZero() {*this = Base{};} // use operator= to assign zeros
};
class Derived : public Base
{
double d = 0.; // notice the = 0. here
public:
Derived () { } // nothing
void setZero() override {*this = Derived{};}
};
we can avoid rewriting setZero as well:
template<class D, class B=void>
struct SetZero:B {
void setZero() override {
*static_cast<D*>(this) = D{};
}
};
template<class D>
struct SetZero<D,void> {
virtual void setZero() {
*static_cast<D*>(this) = D{};
}
};
now we can:
class Base:public SetZero<Base>
{
int x = 0; // notice the =0 here
public:
A() {} // nothing
};
class Derived : public SetZero<Derived, Base>
{
double d = 0.; // notice the = 0. here
public:
Derived () { } // nothing
};
and setZero is written for us.
The DRY here is that default construction zeros, and we put the zeros right next to where we declare variables. setZero then just becomes a helper method to copy over yourself with a default constructed object.
Now, exposing value semantics copy/move operations on a class with a vtable is a bad plan. So you probably want to make the copy/move protected and add friend declarations.
template<class D, class B=void>
struct SetZero:B {
void setZero() override {
*static_cast<D*>(this) = D{};
}
SetZero()=default;
protected:
SetZero(SetZero&&)=default;
SetZero& operator=(SetZero&&)=default;
SetZero(SetZero const&)=default;
SetZero& operator=(SetZero const&)=default;
~SetZero() override=default;
};
template<class D>
struct SetZero<D,void> {
virtual void setZero() {
*static_cast<D*>(this) = D{};
}
SetZero()=default;
protected:
SetZero(SetZero&&)=default;
SetZero& operator=(SetZero&&)=default;
SetZero(SetZero const&)=default;
SetZero& operator=(SetZero const&)=default;
virtual ~SetZero()=default;
};
so those get longer.
In Base and Derived as they have vtables, you are recommended to add
protected:
Derived(Derived&&)=default;
Derived& operator=(Derived&&)=default;
};
to block external access to move/copy construct and move/copy assign. This is advised regardless of how you write setZero (any such move/copy is going to risk slicing, so exposing it to all users of your class is a bad plan. Here I make it protected, because setZero relies on it to make zeroing DRY.)
Another approach is a two-phase construction. In it, we mark all "raw" constructors are protected.
class Base {
int x;
protected:
Base() {} // nothing
public:
virtual setZero() { x = 0; }
};
we then add a non-constructor constructor:
class Base {
int x;
protected:
Base() {} // nothing
public:
template<class...Ts>
static Base Construct(Ts&&...ts){
Base b{std::forward<Ts>(ts)...};
b.setZero();
}
virtual setZero() { x = 0; }
};
and external users have to Base::Construct to get a Base object. This sort of sucks, because our type is no longer regular, but we already have vtable, which makes it unlikely to be regular in the first place.
We can CRTP it;
template<class D, class B=void>
struct TwoPhaseConstruct:B {
template<class...Ts>
D Construct(Ts&&...ts) {
D d{std::forward<Ts>(ts...));
d.setZero();
return d;
}
};
template<class D>
struct TwoPhaseConstruct<D,void> {
template<class...Ts>
D Construct(Ts&&...ts) {
D d{std::forward<Ts>(ts...));
d.setZero();
return d;
}
};
class Base:public TwoPhaseConstruct<Base> {
int x;
protected:
Base() {} // nothing
public:
virtual setZero() { x = 0; }
};
class Derived:public TwoPhaseConstruct<Derived, Base> {
int y;
protected:
Derived() {} // nothing
public:
virtual setZero() { Base::setZero(); y = 0; }
};
and here goes down the rabbit hole, if you want to make_shared or similar we have to add a helper type.
template<class F>
struct constructor_t {
F f;
template<std::constructible_from<std::invoke_result_t<F const&>> T>
operator T()const&{ f(); }
template<std::constructible_from<std::invoke_result_t<F&&>> T>
operator T()&&{ std::move(f)(); }
};
which lets us
auto pBase = std::make_shared<Base>( constructor_t{[]{ return Base::Construct(); }} );
but how far down the rabbit hole do you want to go?
Alternatively to the other answers, separating functionality from API lets you use the general flow you want while dodging the whole "using the vtable in the constructor" issue.
class Base
{
public:
Base() {
setZeroImpl_();
}
virtual void setZero() {
setZeroImpl_();
}
private:
void setZeroImpl_() {
std::cout << "Set all Base class values to zeros (default) values";
}
};
class Derived : public Base
{
public:
Derived () {
setZeroImpl_();
}
void setZero() override {
Base::setZero();
setZeroImpl_();
}
private:
void setZeroImpl_() {
std::cout << "Set all Derived class values to zeros (default) values";
}
};
You could solve it this way:
#include <iostream>
class Base
{
public:
Base() { Base::setZero();}
virtual void setZero() {std::cout << "Set all Base class values to zeros (default) values\n";}
protected:
Base(bool) {};
};
class Derived : public Base
{
public:
Derived () : Base(true) { Derived::setZero(); }
void setZero() override {
Base::setZero();
std::cout << "Set all Derived class values to zeros (default) values\n";
}
};
What I have done, is the following:
Make clear which setZero() method is called by which constructor
Added call to setZero()also from the Derived constructor
Added a protected Base constructor that does not call its setZero() method, and calling this constructor from Derived's constructor, so that Base::setZero()is called exactly once during creation of a Derived object.
By doing it this way, you can create Base or Derived and call zerZero() as intended.
You could implement a simple factory method in your Derived class and remove the setZero() calls from the constructors alltogether. Then making the constructors non-public will tell consumers of the class to use the factory method for proper instantiation instead of the constructor. Something like this:
class Base
{
protected:
Base() { }
virtual void setZero() {std::cout << "Set all Base class values to zeros (default) values";}
};
class Derived : public Base
{
public:
static Derived createInstance()
{
Derived derived;
derived.setZero();
return derived;
}
private:
Derived() { }
void setZero() override {
Base::setZero();
std::cout << "Set all Derived class values to zeros (default) values";
}
};
And then create your instance of Derived somehow like this:
int main()
{
Derived derived = Derived::createInstance();
// do something...
return 0;
}
With this approach you can also make sure that no one can create an instance of your class that is not in a valid state.
Note: Don't know if you use the base class at some places directly but if this is the case you could provide a factory method for it as well.
If I understand your question correctly, then what you need to do is below simply
#include <iostream>
using std::cout;
using std::endl;
class Base
{
void init() {std::cout << "Set all Base class values to zeros (default) values" << endl;}
public:
Base() {init(); }
virtual void setZero() {init();}
};
class Derived : public Base
{
void init() { std::cout << "Set all Derived class values to zeros (default) values" << endl; }
public:
Derived () { init(); }
void setZero() override {
Base::setZero();
init();
}
};
int main()
{
Derived d1;
cout << endl;
d1.setZero();
}
You wrote the below statement for your code
But it's all doesn't work as intended as dynamic binding doesn't work when function is called from the constructor.
Yes, the virtual behavior will not work, when calling setZero() from the base class constructor, and the reason is that derived class has not been constructed yet.
What you need is to initialize each class when its constructed, and that should happen in there respective constructors, and that is what we do in the above code.
Base class constructor will call its own setZero, derived class constructor will call its own setZero.
And you will continue to do the same thing, if you derive any further class from Derived class.
Can anyone let me know how to achieve:
the parameter of a method of a derived class being the parameter's
derived class (not the parameter's base class)?
This is what I want:
class Base{
public:
// Base class method has ParameterBase parameter
virtual void f(ParameterBase pb) = 0;
}
class Derived : public Base{
public:
// I want: Derived class method has ParameterDerived parameter;
void f(ParameterDerived pd){ //do something with pd; }
}
class ParameterBase{
// Base class of parameter;
}
class ParameterDerived : public ParameterBase{
// Derived class of parameter;
}
How to achieve above?
Do I have to use ParamterBase in the derived method's parameter list and dynamic_cast the parameter in the method body?
The feature you are asking for is called parameter type contra-variance. And C++ unfortunately, doesn't support it. C++ supports just the return type covariance. See here for a nice explanation.
Perhaps inconveniently, C++ does not permit us to write the function
marked hmm... above. C++’s classical OOP system supports “covariant
return types,” but it does not support “contravariant parameter
types.”
But you can use dynamic_cast<>() operator. But first, you must change the parameter type to pointer or reference, and add at least one virtual member (virtual destructor counts too) to your class ParameterBase to make compiler to create virtual method table for it. Here is the code with references. Pointers can be used instead.
class ParameterBase
{
public:
// To make compiler to create virtual method table.
virtual ~ParameterBase()
{}
};
class ParameterDerived : public ParameterBase
{
};
class Base
{
public:
// Pointers or references should be used here.
virtual void f(const ParameterBase& pb) = 0;
};
class Derived : public Base
{
public:
virtual void f(const ParameterBase& pb) override
{
// And here is the casting.
const ParameterDerived& pd=dynamic_cast<const ParameterDerived&>(pb);
}
};
int main()
{
Derived d;
ParameterDerived p;
d.f(p);
}
Supposing you want Derived to be called with ParameterDerived, but you also want to declare the interface in abstract base classes.
The interface MUST have the same parameter types, but you can still enforce the right parameter subclass with a dynamic_cast inside Derived::f
#include <iostream>
#include <string>
// interface
struct ParameterBase {
virtual ~ParameterBase() {};
};
struct Base {
virtual void f(ParameterBase *pb) = 0;
virtual ~Base() {};
};
// specific
struct ParameterDerived : public ParameterBase {
std::string name;
ParameterDerived(const std::string &name) : name(name) {}
ParameterDerived& operator=(const ParameterDerived& rhs) { name = rhs.name; }
~ParameterDerived() {};
};
struct Derived : public Base {
Derived(){}
Derived& operator=(const Derived &rhs) {}
virtual ~Derived(){}
void f(ParameterBase *pb) {
ParameterDerived *pd = dynamic_cast<ParameterDerived*>(pb);
if (pd) {
std::cout << "Derived object with derived parameter " << pd->name << std::endl;
} // else {throw std::exception("wrong parameter type");}
}
};
int main() {
Derived object;
ParameterDerived param("foo");
object.f(¶m);
}
I have a base class MyBase that contains a pure virtual function:
void PrintStartMessage() = 0
I want each derived class to call it in their constructor
then I put it in base class(MyBase) constructor
class MyBase
{
public:
virtual void PrintStartMessage() =0;
MyBase()
{
PrintStartMessage();
}
};
class Derived:public MyBase
{
public:
void PrintStartMessage(){
}
};
void main()
{
Derived derived;
}
but I get a linker error.
this is error message :
1>------ Build started: Project: s1, Configuration: Debug Win32 ------
1>Compiling...
1>s1.cpp
1>Linking...
1>s1.obj : error LNK2019: unresolved external symbol "public: virtual void __thiscall MyBase::PrintStartMessage(void)" (?PrintStartMessage#MyBase##UAEXXZ) referenced in function "public: __thiscall MyBase::MyBase(void)" (??0MyBase##QAE#XZ)
1>C:\Users\Shmuelian\Documents\Visual Studio 2008\Projects\s1\Debug\s1.exe : fatal error LNK1120: 1 unresolved externals
1>s1 - 2 error(s), 0 warning(s)
I want force to all derived classes to...
A- implement it
B- call it in their constructor
How I must do it?
There are many articles that explain why you should never call virtual functions in constructor and destructor in C++. Take a look here and here for details what happens behind the scene during such calls.
In short, objects are constructed from the base up to the derived. So when you try to call a virtual function from the base class constructor, overriding from derived classes hasn't yet happened because the derived constructors haven't been called yet.
Trying to call a pure abstract method from a derived while that object is still being constructed is unsafe. It's like trying to fill gas into a car but that car is still on the assembly line and the gas tank hasn't been put in yet.
The closest you can get to doing something like that is to fully construct your object first and then calling the method after:
template <typename T>
T construct_and_print()
{
T obj;
obj.PrintStartMessage();
return obj;
}
int main()
{
Derived derived = construct_and_print<Derived>();
}
You can't do it the way you imagine because you cannot call derived virtual functions from within the base class constructor—the object is not yet of the derived type. But you don't need to do this.
Calling PrintStartMessage after MyBase construction
Let's assume that you want to do something like this:
class MyBase {
public:
virtual void PrintStartMessage() = 0;
MyBase() {
printf("Doing MyBase initialization...\n");
PrintStartMessage(); // ⚠ UB: pure virtual function call ⚠
}
};
class Derived : public MyBase {
public:
virtual void PrintStartMessage() { printf("Starting Derived!\n"); }
};
That is, the desired output is:
Doing MyBase initialization...
Starting Derived!
But this is exactly what constructors are for! Just scrap the virtual function and make the constructor of Derived do the job:
class MyBase {
public:
MyBase() { printf("Doing MyBase initialization...\n"); }
};
class Derived : public MyBase {
public:
Derived() { printf("Starting Derived!\n"); }
};
The output is, well, what we would expect:
Doing MyBase initialization...
Starting Derived!
This doesn't enforce the derived classes to explicitly implement the PrintStartMessage functionality though. But on the other hand, think twice whether it is at all necessary, as they otherwise can always provide an empty implementation anyway.
Calling PrintStartMessage before MyBase construction
As said above, if you want to call PrintStartMessage before the Derived has been constructed, you cannot accomplish this because there is no yet a Derived object for PrintStartMessage to be called upon. It would make no sense to require PrintStartMessage to be a non-static member because it would have no access to any of the Derived data members.
A static function with factory function
Alternatively we can make it a static member like so:
class MyBase {
public:
MyBase() {
printf("Doing MyBase initialization...\n");
}
};
class Derived : public MyBase {
public:
static void PrintStartMessage() { printf("Derived specific message.\n"); }
};
A natural question arises of how it will be called?
There are two solution I can see: one is similar to that of #greatwolf, where you have to call it manually. But now, since it is a static member, you can call it before an instance of MyBase has been constructed:
template<class T>
T print_and_construct() {
T::PrintStartMessage();
return T();
}
int main() {
Derived derived = print_and_construct<Derived>();
}
The output will be
Derived specific message.
Doing MyBase initialization...
This approach does force all derived classes to implement PrintStartMessage. Unfortunately it's only true when we construct them with our factory function... which is a huge downside of this solution.
The second solution is to resort to the Curiously Recurring Template Pattern (CRTP). By telling MyBase the complete object type at compile time it can do the call from within the constructor:
template<class T>
class MyBase {
public:
MyBase() {
T::PrintStartMessage();
printf("Doing MyBase initialization...\n");
}
};
class Derived : public MyBase<Derived> {
public:
static void PrintStartMessage() { printf("Derived specific message.\n"); }
};
The output is as expected, without the need of using a dedicated factory function.
Accessing MyBase from within PrintStartMessage with CRTP
While MyBase is being executed, its already OK to access its members. We can make PrintStartMessage be able to access the MyBase that has called it:
template<class T>
class MyBase {
public:
MyBase() {
T::PrintStartMessage(this);
printf("Doing MyBase initialization...\n");
}
};
class Derived : public MyBase<Derived> {
public:
static void PrintStartMessage(MyBase<Derived> *p) {
// We can access p here
printf("Derived specific message.\n");
}
};
The following is also valid and very frequently used, albeit a bit dangerous:
template<class T>
class MyBase {
public:
MyBase() {
static_cast<T*>(this)->PrintStartMessage();
printf("Doing MyBase initialization...\n");
}
};
class Derived : public MyBase<Derived> {
public:
void PrintStartMessage() {
// We can access *this member functions here, but only those from MyBase
// or those of Derived who follow this same restriction. I.e. no
// Derived data members access as they have not yet been constructed.
printf("Derived specific message.\n");
}
};
No templates solution—redesign
Yet another option is to redesign your code a little. IMO this one is actually the preferred solution if you absolutely have to call an overridden PrintStartMessage from within MyBase construction.
This proposal is to separate Derived from MyBase, as follows:
class ICanPrintStartMessage {
public:
virtual ~ICanPrintStartMessage() {}
virtual void PrintStartMessage() = 0;
};
class MyBase {
public:
MyBase(ICanPrintStartMessage *p) : _p(p) {
_p->PrintStartMessage();
printf("Doing MyBase initialization...\n");
}
ICanPrintStartMessage *_p;
};
class Derived : public ICanPrintStartMessage {
public:
virtual void PrintStartMessage() { printf("Starting Derived!!!\n"); }
};
You initialize MyBase as follows:
int main() {
Derived d;
MyBase b(&d);
}
You shouldn't call a virtual function in a constructor. Period. You'll have to find some workaround, like making PrintStartMessage non-virtual and putting the call explicitly in every constructor.
If PrintStartMessage() was not a pure virtual function but a normal virtual function, the compiler would not complain about it. However you would still have to figure out why the derived version of PrintStartMessage() is not being called.
Since the derived class calls the base class's constructor before its own constructor, the derived class behaves like the base class and therefore calls the base class's function.
I know this is an old question, but I came across the same question while working on my program.
If your goal is to reduce code duplication by having the Base class handle the shared initialization code while requiring the Derived classes to specify the code unique to them in a pure virtual method, this is what I decided on.
#include <iostream>
class MyBase
{
public:
virtual void UniqueCode() = 0;
MyBase() {};
void init(MyBase & other)
{
std::cout << "Shared Code before the unique code" << std::endl;
other.UniqueCode();
std::cout << "Shared Code after the unique code" << std::endl << std::endl;
}
};
class FirstDerived : public MyBase
{
public:
FirstDerived() : MyBase() { init(*this); };
void UniqueCode()
{
std::cout << "Code Unique to First Derived Class" << std::endl;
}
private:
using MyBase::init;
};
class SecondDerived : public MyBase
{
public:
SecondDerived() : MyBase() { init(*this); };
void UniqueCode()
{
std::cout << "Code Unique to Second Derived Class" << std::endl;
}
private:
using MyBase::init;
};
int main()
{
FirstDerived first;
SecondDerived second;
}
The output is:
Shared Code before the unique code
Code Unique to First Derived Class
Shared Code after the unique code
Shared Code before the unique code
Code Unique to Second Derived Class
Shared Code after the unique code
Facing the same problem, I imaginated a (not perfect) solution. The idea is to provide a certificate to the base class that the pure virtual init function will be called after the construction.
class A
{
private:
static const int checkValue;
public:
A(int certificate);
A(const A& a);
virtual ~A();
virtual void init() = 0;
public:
template <typename T> static T create();
template <typeneme T> static T* create_p();
template <typename T, typename U1> static T create(const U1& u1);
template <typename T, typename U1> static T* create_p(const U1& u1);
//... all the required possibilities can be generated by prepro loops
};
const int A::checkValue = 159736482; // or any random value
A::A(int certificate)
{
assert(certificate == A::checkValue);
}
A::A(const A& a)
{}
A::~A()
{}
template <typename T>
T A::create()
{
T t(A::checkValue);
t.init();
return t;
}
template <typename T>
T* A::create_p()
{
T* t = new T(A::checkValue);
t->init();
return t;
}
template <typename T, typename U1>
T A::create(const U1& u1)
{
T t(A::checkValue, u1);
t.init();
return t;
}
template <typename T, typename U1>
T* A::create_p(const U1& u1)
{
T* t = new T(A::checkValue, u1);
t->init();
return t;
}
class B : public A
{
public:
B(int certificate);
B(const B& b);
virtual ~B();
virtual void init();
};
B::B(int certificate) :
A(certificate)
{}
B::B(const B& b) :
A(b)
{}
B::~B()
{}
void B::init()
{
std::cout << "call B::init()" << std::endl;
}
class C : public A
{
public:
C(int certificate, double x);
C(const C& c);
virtual ~C();
virtual void init();
private:
double x_;
};
C::C(int certificate, double x) :
A(certificate)
x_(x)
{}
C::C(const C& c) :
A(c)
x_(c.x_)
{}
C::~C()
{}
void C::init()
{
std::cout << "call C::init()" << std::endl;
}
Then, the user of the class can't construct an instance without giving the certificate, but the certificate can only be produced by the creation functions:
B b = create<B>(); // B::init is called
C c = create<C,double>(3.1415926535); // C::init is called
Moreover, the user can't create new classes inheriting from A B or C without implementing the certificate transmission in the constructor. Then, the base class A has the warranty that init will be called after construction.
I can offer a work around / "companion" to your abstract base class using MACROS rather than templates, or staying purely within the "natural" constraints of the language.
Create a base class with an init function e.g.:
class BaseClass
{
public:
BaseClass(){}
virtual ~BaseClass(){}
virtual void virtualInit( const int i=0 )=0;
};
Then, add a macro for a constructor. Note there is no reason to not add multiple constructor definitions here, or have multiple macros to choose from.
#define BASECLASS_INT_CONSTRUCTOR( clazz ) \
clazz( const int i ) \
{ \
virtualInit( i ); \
}
Finally, add the macro to your derivation:
class DervivedClass : public BaseClass
{
public:
DervivedClass();
BASECLASS_INT_CONSTRUCTOR( DervivedClass )
virtual ~DervivedClass();
void virtualInit( const int i=0 )
{
x_=i;
}
int x_;
};
Long story short, what I want here is to declare a templated type in a base class and be able to access that type A<T> such that the base class B contains it and the derived class C is able to access it as C::A<T>. I did try declaring an int inside of class B and that can be accessed from the derived C class as C::int, here's the error!
||In constructor ‘D::D()’:|
|74|error: no match for ‘operator=’ (operand types are ‘A<C*>’ and ‘A<B*>’)|
|4|note: candidate: A<C*>& A<C*>::operator=(const A<C*>&)|
|4|note: no known conversion for argument 1 from ‘A<B*>’ to ‘const A<C*>&’|
And this is the code that does compile ( comment A<B*> i; and uncomment A<C*> i; to get the error).
#include <iostream>
//class with a template parameter
template <class a>
class A
{
private:
int somevalue;
public:
A(){}
~A(){}
void print()
{
std::cout<<somevalue<<std::endl;
}
};
//1. could forward declare
class C;
class B
{
protected:
A<B*> i;
//2. and then use
//A<C*> i;
public:
B(){}
~B(){}
A<B*> get()
{
return i;
}
/*
//3. use this return instead
A<C*> get()
{
return i;
}
*/
};
//specialization of B that uses B's methods variables
class C : public B
{
protected:
public:
C(){}
virtual ~C(){}
void method()
{
B::i.print();
}
};
//class D that inherits the specialization of C
class D : public C
{
private:
A<B*> i;//works
//4. but I want the inherited type to work like
//A<C*> i;// so that the type C* is interpreted as B*
public:
D()
{
this->i = C::i;
}
~D(){}
};
///////////////////////////////////////////////////////////////////////
int main()
{
D* d = new D();
delete d;
return 0;
}
But okay what if we tried this std::list<template parameter> LIST and then plug that in? That's the problem A<T> is std::list.
As far as I understand your issue now you seem to have a std::list<Base *> (renamed B to Base for clarity) and want to fill an std::list<Concrete*> (renamed C to Concrete, it's derived from Base) with it.
For that you need to iterate over the Base* pointers, checking for each whether it can be downcast to a Concrete* and if so adding it to the std::list<Concrete*>. You need to think about what to do if the downcast fails, too.
For all of this to work your Base needs to be a polymorphic base class, that is it must contain a virtual member function (don't forget to make the destructor virtual). Also note that this sounds like a catastrophe waiting to happen in terms of managing ownership of those pointers.
template<typename Base, typename Concrete>
std::list<Concrete*> downcast_list (std::list<Base*> const & bases) {
std::list<Concrete*> result;
for (auto const base_ptr : bases) {
Concrete * concrete_ptr = dynamic_cast<Concrete*>(base_ptr);
if (concrete_ptr != nullptr) {
result.push_back(concrete_ptr);
} else {
// Error or ignore?
}
}
return result;
}
Note: a more idiomatic version of this would use iterators.
I found the pattern to my problem, it's actually really simple and it serves as the base for encapsulating a class type a (which is a template parameter to be passed around, try looking at my question as a reference to class a). The pattern is shown below, it's generally what I wanted. I found it on this webpage Using Inheritance Between Templates chapter 7.5 from the book entitled OBJECT-ORIENTED
SOFTWARE DESIGN
and CONSTRUCTION
with C++ by Dennis Kafura. I'll copy it below the edited code for the sake of future reference in case anyone else needs it.
template <class a>
class B
{
private:
public:
B();
~B();
};
template <class a>
class C : public B<a>
{
public:
C();
~C();
};
This is the code it was adapted from.
template <class QueueItem> class Queue
{
private:
QueueItem buffer[100];
int head, tail, count;
public:
Queue();
void Insert(QueueItem item);
QueueItem Remove();
~Queue();
};
template <class QueueItem> class InspectableQueue : public Queue<QueueItem>
{
public:
InspectableQueue();
QueueItem Inspect(); // return without removing the first element
~InspectableQueue();
};
Try changing this:
#include <iostream>
//class with a template parameter
template <class a>
class A {
private:
int somevalue;
public:
A(){}
~A(){}
void print() {
std::cout<<somevalue<<std::endl;
}
};
//1. could forward declare
class C;
class B {
protected:
A<B*> i;
//2. and then use
//A<C*> i;
public:
B(){}
~B(){}
A<B*> get() {
return i;
}
/*/3. use this return instead
A<C*> get() {
return i;
} */
};
//specialization of B that uses B's methods variables
class C : public B {
protected:
public:
C(){}
virtual ~C(){}
void method() {
B::i.print();
}
};
//class D that inherits the specialization of C
class D : public C {
private:
A<B*> i;//works
//4. but I want the inherited type to work like
//A<C*> i;// so that the type C* is interpreted as B*
public:
D() {
this->i = C::i;
}
~D(){}
};
int main() {
D* d = new D();
delete d;
return 0;
}
To Something Like This:
#include <iostream>
//class with a template parameter
template <typename T>
class Foo {
private:
T value_;
public:
Foo(){} // Default
Foo( T value ) : value_(value) {}
~Foo(){}
void print() {
std::cout<< value_ << std::endl;
}
};
class Derived;
class Base {
protected:
Foo<Base*> foo_;
Base(){} // Default;
virtual ~Base(){}
// Overload This Function
template<typename T = Base>
/*virtual*/ Foo<T*> get();
/*virtual*/ Foo<Base*> get() { return this->foo_; }
/*virtual*/ Foo<Derived*> get();
};
class Derived : Base {
public:
Derived() {}
virtual ~Derived() {}
void func() {
Base::foo_.print();
}
void Foo<Derived*> get() override { return this->foo_; }
};
And this is as about as far as I could get trying to answering your question...
There are objects that you are not using in your code
There are methods that aren't being called.
It is kind of hard to understand the direction/indirection
of what you mean to do with the inheritance tree.
You are inheriting from a base class without a virtual destructor
And probably a few other things that I can not think of off the top of my head right now.
I'd be more than willing to try and help you out; but this is as far as I can go with what you currently are showing.
EDIT -- I made changes to the base & derived classes and removed the virtual keyword to the overloaded function template declarations - definitions belonging to those classes.