我们可以拥有静态虚函数吗?如果没有,那么为什么?

Jat*_*tin 54 c++ static-methods virtual-functions

可能重复:
C++静态虚拟成员?

我们可以拥有静态虚函数吗?如果没有,那么为什么?

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

Oli*_*rth 71

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

当您具有指向类实例的指针/引用时,将调用虚函数.静态函数不依赖于特定实例,它们与类绑定.C++没有指向类的指针,因此没有可以虚拟调用静态函数的场景.

  • 该语言可以轻松决定为每个类添加静态虚函数表 (27认同)
  • 值得尊敬的是,虚拟静态成员确实对某些用途和某些人有用.@OliverCharlesworth,考虑改写你的答案或详细说明.是的,我意识到它被接受了,但是,它的立场并不是真的. (8认同)
  • "没有任何意义"?Python中的类方法怎么样? (4认同)
  • @OliCharlesworth:对。没有理由不存在-只是没有发生。但这当然是有道理的(并且会很有用)。 (4认同)
  • 如果需要,您可以在对象上调用静态函数,对吧?因此在这种情况下,您可以使用 vtable 来确定要调用的函数版本。当从类本身的非静态成员函数内部调用时,它尤其有意义。 (3认同)
  • @OliCharlesworth:当您拥有某种工厂(例如虚拟构造函数)时,我认为这可能有意义。 (2认同)
  • 如果我有时只想将该函数用作普通静态函数,但当我在类层次结构中使用它时也希望具有多态性,该怎么办? (2认同)

Ker*_* SB 15

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

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); }
};
Run Code Online (Sandbox Code Playgroud)

用法:

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

// Normal use of statics:
Base::foo(b);
Derived::bar(-8, true);
Run Code Online (Sandbox Code Playgroud)

  • SO上的每个C++问题都回答"因为它没有意义"吗?我刚刚创建了一个虚拟方法,因为它必须被覆盖,然后我意识到它没有(并且真的_mustn't_)触摸任何实例数据,因此添加了静态,这就是我在这个页面上的结果.这个答案提供了一个解决方法(+1),但没有回答这个问题,因为"它毫无意义"是完全错误的. (36认同)
  • 你一直说它"毫无意义"但你提供的例子表明,语言决定支持它是一个合理的事情 - 在派生类中调用静态函数. (17认同)
  • `static`并不仅仅意味着它可以在没有类的实例的情况下被调用; 它也是一个承诺,它不会访问`this`.它有点接近纯函数(如`constexpr`,显然也禁止`virtual`).函数既可以是纯函数(在数学意义上)也可以是虚函数.C++只是强制要求这样一个函数接收一个虚假的`this`指针,它取消了在派生类上强制执行`static`契约的可能性. (7认同)
  • @Inverse还有什么可以`Base`在运行时除了`Base`? (2认同)
  • 如果函数是纯虚拟的,那么它可以有一个感觉.如果你没有在派生类中重载它,那么编译器会出错.可以考虑使用getInstance()函数来制作单例.您可能希望签订一个合同,声明从此Base派生的每个类都必须具有getInstance().您希望编译器为您检查. (2认同)
  • 只是想表现出对 sh1 的一些支持。如果 C++ 是许多开发人员暗示的超级严格的每个关键字意味着一个事物总是语言,那么它“没有意义”,但事实并非如此。虽然 `static virtual` 的实现显然不会像普通的 static 那样工作,但“虚拟”的作用不止一个部分。在这种情况下,如果未定义静态函数,他会查找编译器错误。编译器可以很容易地做到这一点,而忽略 vtables。多功能动词是真实的。 (2认同)