Question

I want to create an abstract class that has a pure virtual function that is called by the constructor that is NOT purely virtual. Below is my file class.hpp:

#ifndef __CLASS_HPP__
#define __CLASS_HPP__

#include <iostream>

class Parent {
 public:
  Parent(){
    helloWorld(); // forced to say hello when constructor called                    
  };
  virtual void helloWorld() = 0; // no standard hello...                            
};

class Child : public Parent {
 public:
  void helloWorld(){ // childs implementation of helloWorld                         
    std::cout << "Hello, World!\n";
  };
};

#endif

In this example, I have a parent class that has a pure virtual function helloWorld(). I want every derived class to say "hello" when the constructor is called; hence why helloWorld() is in the parent class constructor. However, I want every derived class to be FORCED to choose how its going go say "hello", rather than having a default method. Is this possible? If I try to compile this with g++, I get the error that a pure virtual function is being called by the constructor. My main.cpp is:

#include "class.hpp"

int main(){
  Child c;
  return 0;
}

I am compiling using g++ main.cpp -o main.out and the resulting error is:

In file included from main.cpp:1:0:
class.hpp: In constructor ‘Parent::Parent()’:  
class.hpp:9:16: warning: pure virtual ‘virtual void Parent::helloWorld()’ called from constructor [enabled by default]

Any suggestions for how to get a similar setup in a legal way?

NEW QUESTION

DyP has brought to my attention that a constructor does not use any overridden functions, so what I want to be able to do isn't possible in the way I have it setup. However, I still would like to force any derived constructor to call the function helloWorld(), is there any way to do this?

Was it helpful?

Solution 2

Why don't you simply add it to the constructor of the every child class?

If you want to avoid writing it every time in the constructor (or even skipping or inheriting it) then you could use CRTP:

class Parent {
 public:
  Parent(){};
  virtual void helloWorld() = 0; // no standard hello...                            
};

template <typename Par>
class ParentCRTP: public Parent {
 public:
  ParentCRTP(){
    Par::doHelloWorld();
  };
  virtual void helloWorld(){
    Par::doHelloWorld();
  }
};

class Child : public ParentCRTP<Child> {
 public:
  static void doHelloWorld(){ // childs implementation of helloWorld                         
    std::cout << "Hello, World!\n";
  };
};

This approach will not give you a pointer to the child class in your child's hello method - at this point class instance is only Parent instance, no valid Child pointer can be obtained. To force an execution of Child's method after construction you can only use two stage initialization: First you create class instance using a constructor, and then initialize it using separate method.

Apart from that, problem like this is probably a hint to re-think your design. You shouldn't force your classes to initialize itself in a given way.

OTHER TIPS

What you are doing is illegal.

In order to define a abstract class in C++ your class must have at least one pure virtual function. In your case

virtual void helloWorld() = 0;

in this case you are right.

But your pure virtual function have no any implementation, since it is a pure virtual function. So it is illegal to call pure virtual function from the constuructor of the same class.(In class level pure virtual function have no any implementation)

So,

Parent(){
helloWorld(); // forced to say hello when constructor called                    
};

this is illegal.

If you want, you can implement your pure virtual function in derived class and then call helloWorld() from constructor of derived class

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top