覆盖纯虚函数的参数数量

发布于 2024-09-03 11:48:59 字数 466 浏览 3 评论 0原文

我已经实现了以下接口:

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

正确的派生类将定义如下:

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

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

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 Callback accepts different parameters (eg: void Callback (int a, int b)).
Is there a way to do it?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

雨后彩虹 2024-09-10 11:48:59

这是我多次遇到的问题。

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

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;
};

在行动中:

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

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
送舟行 2024-09-10 11:48:59

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

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.

恬淡成诗 2024-09-10 11:48:59

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

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.

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.
土豪 2024-09-10 11:48:59

我知道这是一个公认的答案,但是有一种(丑陋的)方法可以实现你想要的,尽管我不会推荐它:

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, ...) {
  } 
};  

现在,你可以使用:

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

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

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

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 values argument in order to obtain the remaining arguments inside the method. You also need to know the argument types, and pass them like printf does.

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

鲜血染红嫁衣 2024-09-10 11:48:59

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

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.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文