call to pure virtual function from base class constructor
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.
Calling pure virtual function in constructor gives an error
Calling virtual functions in a constructor is recognised as a bad thing to do.
During base class construction of a derived class object, the type of
the object is that of the base class. Not only do virtual functions
resolve to the base class, but the parts of the language using runtime
type information (e.g., dynamic_cast (see Item 27) and typeid) treat
the object as a base class type.
So your instantiation of b
invokes the a
constructor. That calls foo()
, but it's the foo()
on a
that gets called. And that (of course) is undefined.
Calling Pure Virtual Function From Abstract Base Class Member Function?
Func is calling the virtual ones, not the pure virtual ones. You would have to qualify the calls with a scope operator, i.e. AbstractClass::Step1() to call THAT (virtual pure) function. Since you are not, you will always get an implementation by a derived class.
how to call pure virtual function from base class if that function is defined in more than 2 derived class
The whole point of pure virtual functions is to actually decouple the concrete implementation from the abstract base class interface.
If you are calling the pureFunc()
through a Base*
pointer or reference, the calling code should be agnostic about the implementations in D1
and D2
, and thus shouldn't need to know which one is actually called.
Calling virtual functions inside constructors
Calling virtual functions from a constructor or destructor is dangerous and should be avoided whenever possible. All C++ implementations should call the version of the function defined at the level of the hierarchy in the current constructor and no further.
The C++ FAQ Lite covers this in section 23.7 in pretty good detail. I suggest reading that (and the rest of the FAQ) for a followup.
Excerpt:
[...] 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.
EDIT Corrected Most to All (thanks litb)
(Why) Is virtual base class constructor call required in pure virtual derived class?
Design issues (which clearly exist here) aside, I fully agree with your reasoning that, because Left
is an abstract class, no Left
constructor will ever have to call any Base
constructor and thus it is odd that it is required.
In fact, I tested your code with several compiler versions and it does compile just fine with gcc 7.1 and onwards, with clang 3.4.1 and onwards, and with all available msvc versions.
So, my assumption is, that this was just a bug in earlier compiler versions. Can anyone confirm this?
Also note, if you change virtual void leftsMethod() = 0;
to virtual void leftsMethod() {}
, so that Left
is not abstract anymore, the error returns, even with the latest versions. And this makes perfectly sense, as now you could instantiate a Left
instance and thus it would be up to Left
's constructor to call one of Base
's constructors.
Possible workaround
If you cannot switch to a newer compiler and if you cannot alter the implementation of Base
, this may be a working solution for you:
Define a dummy instance of CustomType
somewhere. Then, you can provide the "required" default constructors like this:
class CustomType{};
class Base
{
public:
Base( CustomType& obj ) : refObj_( obj ) {}
private:
CustomType& refObj_;
};
static CustomType dummy;
class Left : public virtual Base
{
protected:
Left() : Base(dummy) {}; // note here
public:
virtual void leftsMethod() = 0;
};
class Right : public virtual Base
{
protected:
Right() : Base(dummy) {}; // and here
public:
virtual void rightsMethod() = 0;
};
class Bottom : public Left, public Right
{
public:
Bottom( CustomType& obj ) : Base( obj ), Left(), Right() {}
virtual void leftsMethod() override {}
virtual void rightsMethod() override {}
};
void test()
{
CustomType c;
Bottom b(c);
}
This is just to make the compiler happy, your argument that these constructors will never call Base(dummy)
still holds.
Note however, that Base
should really have a virtual destructor! I don't know if you just didn't include it here for brevity or if it really doesn't have one. If it doesn't, it's a very bad idea to build a class hierarchy on top of it.
function called by constructors of derived classes not supposed to be pure virtual in base class
Instead of forcing them to call a function (which you anyway cannot guarantee), make the base class constructor expect a parameter that includes the behavior you need to have.
That way, the base class is self-contained and has all the required information by the time its constructor runs.
For example, if you were thinking of something like this:
class Base
{
public:
Base()
{
reset();
}
protected:
virtual void reset() = 0;
void setValue(int value);
};
class Derived : public Base
{
public:
void reset() override
{
setValue(20);
}
};
you can do this instead:
class Base
{
public:
explicit Base(int value)
{
setValue(value);
}
private: // can be private
void setValue(int value);
};
class Derived : public Base
{
public:
Derived()
: Base(20)
{
}
};
C++ calling pure virtual function from non virtual function in base class
I am aware that you can / should not call virtual functions in the constructor and that a pure virtual destructor is not possible.
Declaring a function pure virtual does not mean that you cannot provide an implementation for it. This applies to destructors as well:
struct Foo {
virtual ~Foo() = 0;
...
};
Foo::~Foo() {
... // Implement destructor
}
The clang compiler then gives me a linker error
Undefined symbols for architecture x86_64:
"Base::bar() const", referenced from:
This usually happens when you incorrectly compile your classes one-by-one, and then do not link them properly. The compiler has a simple way to compile all classes together, and link the results, as follows:
g++ base.cpp child.cpp main.cpp
Note that you need to include headers for the classes in their implementation files, for example
#include "base.h"
int Base::bar() {
return this->foo()*3;
}
Make sure that you fix any errors that come up in the process (hint: the above will produce an error).
Related Topics
How to Use Visual Studio 2010's C++ Compiler with Visual Studio 2008's C++ Runtime Library
Error Enabling Openmp - "Ld: Library Not Found for -Lgomp" and Clang Errors
How to Insert the Value in a Sorted Vector
How to Get the Hmodule for the Currently Executing Code
How to Check If Enum Value Is Valid
Too Many Initializers for 'Int [0]' C++
Is Accessing Data in the Heap Faster Than from the Stack
C++ Equivalent to Java's Blockingqueue
How to Best Handle Dynamic Multi-Dimensional Arrays in C/C++
How to Read-Write Into/From Text File with Comma Separated Values
Random Array Generation with No Duplicates
Linking Libstdc++ Statically: Any Gotchas