C++ 覆盖纯虚函数的参数数量

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/2919584/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-28 11:29:58  来源:igfitidea点击:

Override number of parameters of pure virtual functions

c++interfacevirtualoverloading

提问by Jir

I have implemented the following interface:

我已经实现了以下接口:

template <typename T>
class Variable
{
public:
  Variable (T v) : m_value (v) {}
  virtual void Callback () = 0;
private:
  T m_value;
};

A proper derived class would be defined like this:

一个合适的派生类可以这样定义:

class Derived : public Variable<int>
{
public:
  Derived (int v) : Variable<int> (v) {}
  void Callback () {}
};

However, I would like to derive classes where Callbackaccepts different parameters (eg: void Callback (int a, int b)). Is there a way to do it?

但是,我想派生Callback接受不同参数的类(例如:void Callback (int a, int b))。有没有办法做到这一点?

采纳答案by Matthieu M.

This is a problem I ran in a number of times.

这是我多次运行的问题。

This is impossible, and for good reasons, but there are ways to achieve essentially the same thing. Personally, I now use:

这是不可能的,并且有充分的理由,但是有一些方法可以实现基本相同的目标。就个人而言,我现在使用:

struct Base
{
  virtual void execute() = 0;
  virtual ~Base {}
};

class Derived: public Base
{
public:
  Derived(int a, int b): mA(a), mB(b), mR(0) {}

  int getResult() const { return mR; }

  virtual void execute() { mR = mA + mB; }

private:
  int mA, mB, mR;
};

In action:

在行动:

int main(int argc, char* argv[])
{
  std::unique_ptr<Base> derived(new Derived(1,2));
  derived->execute();
  return 0;
} // main

回答by Oliver Charlesworth

Even if such a thing were possible, it no longer makes much sense to have it as a virtual function, as the derived instantiations couldn't be called polymorphically via a pointer to the base class.

即使这样的事情是可能的,将其作为虚函数也不再有意义,因为无法通过指向基类的指针以多态方式调用派生实例。

回答by RvdK

don't think this will be possible, because you can never interface it back to Variable. This is what i mean

不要认为这是可能的,因为您永远无法将其接口回变量。这就是我的意思

int a=0; int b = 0;
Variable<int>* derived = new Derived();
derived->Callback(a, b); //this won't compile because Variable<int> does not have Callback with 2 vars.

回答by J. Calleja

I know this there is an accepted answer, but there is one (ugly) way to achieve what you want, although I would not recommend it:

我知道这是一个可以接受的答案,但是有一种(丑陋的)方法可以实现您想要的效果,尽管我不推荐它:

template <typename T> 
class Variable 
{ 
public: 
  Variable (T v) : m_value (v) {}
  virtual void Callback (const char *values, ...) = 0; 

private: 
  T m_value; 
};

class Derived : public Variable<int> 
{ 
public: 
  Derived (int v) : Variable<int> (v) {} 
  virtual void Callback (const char *values, ...) {
  } 
};  

Now, you can use:

现在,您可以使用:

  int a=0; 
  double b = 0; 
  Variable<int>* derived = new Derived(3); 
  derived->Callback("");
  derived->Callback("df", a, b);

You need the valuesargument in order to obtain the remaining arguments inside the method. You also need to know the argument types, and pass them like printf does.

您需要values参数才能获取方法内的其余参数。您还需要知道参数类型,并像 printf 一样传递它们。

This method is error prone, as you must match the argument types on valueswith the real argument types.

此方法容易出错,因为您必须将的参数类型与实际参数类型相匹配。

回答by Puppy

You will have to add an overload of Callback in the base class that accepts these parameters. It would also be possible to do bad things, like accept a void*, or pass in a raw pointer-to-bytes. The only scenario in which it is valid to alter virtual function signature is when you override the return value to something polymorphic to the original return value, e.g. *this.

您必须在接受这些参数的基类中添加回调的重载。也有可能做坏事,比如接受一个 void*,或者传入一个原始的指向字节的指针。更改虚函数签名有效的唯一情况是当您将返回值覆盖为原始返回值的多态时,例如 *this。