C++ 覆盖c++;虚拟方法

C++ 覆盖c++;虚拟方法,c++,inheritance,overriding,virtual-functions,C++,Inheritance,Overriding,Virtual Functions,我有一个类模板,其中一些方法被定义为虚拟的,以便类的用户能够在其派生类中为它们提供实现。请注意,在我的模板类中,有一些非虚拟方法使用虚拟方法(应该返回值的虚拟类在非虚拟类中调用) 您能给我一个正确代码的简单示例吗?在这个示例中,父类的虚拟方法应该返回一个值(但它的实现是在子类中提供的),父类中的虚拟方法返回的值用于该类的其他方法。因为我在某个地方看到(例如:)这可能会导致一些问题,并且用户定义的方法将重写父类的虚拟方法 注意:我使用g++编译器使用Code::Blocks编程 编辑:根据要求,这

我有一个类模板,其中一些方法被定义为虚拟的,以便类的用户能够在其派生类中为它们提供实现。请注意,在我的模板类中,有一些非虚拟方法使用虚拟方法(应该返回值的虚拟类在非虚拟类中调用)

您能给我一个正确代码的简单示例吗?在这个示例中,父类的虚拟方法应该返回一个值(但它的实现是在子类中提供的),父类中的虚拟方法返回的值用于该类的其他方法。因为我在某个地方看到(例如:)这可能会导致一些问题,并且用户定义的方法将重写父类的虚拟方法

注意:我使用g++编译器使用Code::Blocks编程

编辑:根据要求,这里有一个我想要的简单示例:

template<typename T>
class parent {
public:
  // Public methods that user can call
  int getSomething(T t);
  void putSomething(T t, int x);

  // public method that user should implement in his code
  virtual float compute(T t) { }

  // protected or private methods and attributes used internally by putSomething ...
  float doComplexeThings(...); // this can call
};
模板
班级家长{
公众:
//用户可以调用的公共方法
int-getSomething(T);
无效(T,int x);
//用户应在其代码中实现的公共方法
虚拟浮点计算(T){}
//putSomething内部使用的受保护或私有方法和属性。。。
float doComplexeThings(…);//这可以调用
};

compute()方法应由用户(子类)实现。但是,例如,putSomething()和doComplexeThings()调用此方法compute()。

您只需确保这些方法具有相同的签名(包括常量/可变修饰符和参数类型)。如果无法重写子类中的函数,则可以使用纯虚拟定义引发编译器错误

class parent {
public:
  // pure virtual method must be provided in subclass
  virtual void handle_event(int something) = 0; 
};

class child : public parent {
public:
  virtual void handle_event(int something) {
    // new exciting code
  }
};

class incomplete_child : public parent {
public:
  virtual void handle_event(int something) const {
    // does not override the pure virtual method
  }
};

int main() {
  parent *p = new child();
  p->handle_event(1); // will call child::handle_event
  parent *p = new incomplete_child(); // will not compile because handle_event
                                      // was not correctly overridden
}

如果您可以在编译器中使用C++11功能,则可以使用
override
特殊标识符标记重写:

 float compute() override;
派生类中的上述行将导致编译器错误,因为该函数未重写基中的成员函数(签名不正确,缺少参数)。但是请注意,这必须在每个派生类中完成,这不是可以从基类强加的解决方案


从基类中,只能通过使函数纯虚拟来强制重写,但这会改变语义。它不会在覆盖时避免问题,而是在所有情况下强制覆盖。我会避免这种方法,如果您要遵循它,并且有一个合理的基类型实现,请将函数设置为虚拟的,并提供一个定义,以便派生类的实现可以将函数调用为基类型(也就是说,您强制实施,但在最简单的情况下,它只会将呼叫转发给家长)

这个问题是在2013年提出的。这个问题很旧,但我发现了一些新的东西,这些答案中不存在

我们需要理解三个概念:重载、覆盖和隐藏

简而言之,您想从基类重载继承函数。 然而,重载是为需要所有这些函数在相同规模下的函数添加多个行为的机制,但虚拟函数显然位于基类中

class A {
public:
  virtual void print() {
    cout << id_ << std::endl;
  }
private:
  string id_ = "A";
};

class B : A {
public:
  using A::print;
  void print(string id) {
    std::cout << id << std::endl;
  }
};

int main(int argc, char const *argv[]) {
  /* code */
  A a;
  a.print();
  B b;
  b.print();
  b.print("B");
  return 0;
}
A类{
公众:
虚拟空打印(){

根据您的描述,可能不需要虚拟方法(静态多态性可能适合您)-根据您的描述很难判断。请发布您编写的示例代码,以便我们更好地了解您正试图执行的操作。链接问题中的示例是关于您认为是重写的内容,但实际上由于错误而声明了重载,例如缺少常量,而不是返回值。您认为如何确切地说,是危险吗?在经典模板代码中,您甚至不需要声明
虚拟浮点计算(T)
。您只需通过
T.compute()在putSomething()和doComplexeThings()中使用它(调用它)
,如果您有实例的句柄。如果您的类T未实现compute,编译器将出错。这样,父级和T实际上不必生活在同一继承层次结构中:即,T是父级关系的子级不需要。这样做还可以给父级一个更有意义的名称(因为不需要is-a关系)。@kfmfe04我不明白你为什么要谈论t和父级之间的关系。t不一定是类,它只是类模板(父级)所使用的类型使用,因为我想使它独立于被操纵数据的类型。忘记T,我的问题只是:在哪里以及如何定义方法
float compute(…)
,该方法由
doComplexeThings(…)
putSomething(…)
调用,而方法的代码
float compute(…)
应该由用户给出。虚拟方法允许使用协变返回类型。@als,只需“允许使用协变返回类型”的一个小细节,只有在函数返回引用或指针时才允许使用协变类型。我知道您知道这一点,但我将把此注释留给其他人。@mschner用您的答案I解决问题s表示您只是为了避免潜在问题而强制更改语义。在最初的情况下,函数存在但可能重载,在您提出的解决方案中,它必须重载。这不会在重载现有函数时处理错误,而是强制派生类重载。+1对于有趣的C++11 fea正确-有助于确保您的方法确实覆盖了某些内容