【问题标题】:Can we have a static virtual functions? If not, then WHY? [duplicate]我们可以有一个静态的虚函数吗?如果不是,那为什么? [复制]
【发布时间】:2012-04-09 10:02:24
【问题描述】:

可能重复:
C++ static virtual members?

我们可以有一个静态的虚函数吗?如果不是,那为什么?

class X
{
public:
       virtual static void fun(){} // Why we cant have static virtual function in C++?
};

【问题讨论】:

  • 一种可能的解决方案是在基类中创建一个静态方法(但不是虚拟方法),并使其在派生类中调用等效的静态方法。这样您仍然可以保持封装和多态性。

标签: c++ static-methods virtual-functions


【解决方案1】:

不,因为它在 C++ 中没有任何意义。

当你有一个指针/引用到一个类的实例时,就会调用虚拟函数。静态函数不绑定到特定实例,它们绑定到类。 C++ 没有指向类的指针,因此没有可以虚拟调用静态函数的场景。

【讨论】:

  • “没有任何意义”? Python 中的类方法呢?
  • 该语言可以很容易地决定为每个类添加一个静态虚函数表
  • @OliCharlesworth:当你有某种工厂(例如虚拟构造函数)时,我认为它可能有意义。
  • @OliCharlesworth:对。没有理由不存在 - 它只是没有发生。但这肯定是有道理的(并且会很有用)。
  • 尊敬的,虚拟静态成员对于某些用途和某些人来说确实有意义。 @OliverCharlesworth,考虑改写你的答案或详细说明。是的,我知道它被接受了,但是,好吧 - 它的现状是不正确的。
【解决方案2】:

那是没有意义的。 virtual 成员函数的意义在于,它们是根据调用它们的 对象实例 的动态类型来调度的。另一方面,静态函数与任何实例无关,而是的属性。因此,它们是虚拟的毫无意义。如果必须,您可以使用非静态调度程序:

struct Base
{
    static void foo(Base & b) { /*...*/ }

    virtual ~Base() { }
    virtual void call_static() { foo(*this); /* or whatever */ }
};

struct Derived : Base
{
     static void bar(int a, bool b) { /* ... */ }

     virtual void call_static() { bar(12, false); }
};

用法:

Base & b = get_instance();
b.call_static();   // dispatched dynamically

// Normal use of statics:
Base::foo(b);
Derived::bar(-8, true);

【讨论】:

  • 您一直说它“没有意义”,但您提供的示例表明,决定支持一种语言可能是合理的——在派生类中调用静态函数。
  • @Inverse Base 在运行时除了Base 之外还有什么?
  • 如果函数是纯虚的 WITH a body 就可以有感觉了。然后,如果您不在派生类中重载它,编译器会出错。例如,考虑一个 getInstance() 函数来制作单例。您可能希望有一个合同,规定从该 Base 派生的每个类都必须有一个 getInstance()。您希望编译器为您检查。
  • 是否每个关于 SO 的 C++ 问题都回答为“因为它没有意义”?我刚刚创建了一个虚拟方法,因为它必须被覆盖,然后我意识到它没有(而且真的不能)接触任何实例数据,所以添加了静态数据,这就是我最终的结果在本页。此答案提供了一种解决方法 (+1),但未能回答问题,因为“这没有任何意义”完全是错误的。
  • static 不仅仅意味着它可以在没有类的实例的情况下被调用;这也是一个承诺,它不会访问this。它在某种程度上近似于纯函数(如constexpr,显然也禁止virtual)。函数既可以是纯函数(在数学意义上),也可以是虚函数。 C++ 仅仅要求这样的函数接收一个虚假的this 指针,它消除了在派生类上强加static 契约的可能性。
猜你喜欢
  • 2011-11-05
  • 2018-08-25
  • 2012-01-28
  • 2010-10-07
  • 1970-01-01
  • 1970-01-01
  • 2011-02-12
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多