简体   繁体   English

非纯虚函数中使用纯虚函数的c ++抽象类

[英]c++ abstract classes using pure virtual functions in non pure virtual functions

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 : 以下是我的文件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() . 在这个例子中,我有一个纯虚拟函数helloWorld()的父类。 I want every derived class to say "hello" when the constructor is called; 我希望每个派生类在调用构造函数时都说“ hello”。 hence why helloWorld() is in the parent class constructor. 因此,为什么helloWorld()在父类构造函数中。 However, I want every derived class to be FORCED to choose how its going go say "hello", rather than having a default method. 但是,我希望每个派生类都必须被强制选择“ hello”,而不要使用默认方法。 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. 如果我尝试使用g ++进行编译,则会收到以下错误:构造函数正在调用纯虚函数。 My main.cpp is: 我的main.cpp是:

#include "class.hpp"

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

I am compiling using g++ main.cpp -o main.out and the resulting error is: 我正在使用g++ main.cpp -o main.out编译,导致的错误是:

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. DyP引起了我的注意,构造函数不使用任何重写的函数,因此,我要设置的方式不可能实现。 However, I still would like to force any derived constructor to call the function helloWorld() , is there any way to do this? 但是,我仍然想强制任何派生的构造函数调用函数helloWorld() ,有什么方法可以做到这一点?

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. 为了在C ++中定义一个抽象类,您的类必须至少具有一个纯虚函数。 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 如果需要,可以在派生类中实现纯虚函数,然后从派生类的构造函数中调用helloWorld()

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: 如果要避免每次都在构造函数中编写它(甚至跳过或继承它),则可以使用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. 这种方法不会在您的孩子的hello方法中为您提供指向该孩子类的指针-此时,类实​​例仅是Parent实例,无法获得有效的Child指针。 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. 要在构造后强制执行Child方法,只能使用两个阶段的初始化:首先,使用构造函数创建类实例,然后使用单独的方法对其进行初始化。

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. 您不应该强迫您的类以给定的方式初始化自身。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM