在 C++ 中,静态成员函数是继承的吗?如果是,为什么不出现歧义错误?

In C++ are static member functions inherited? If yes why ambiguity error does not arise?

我刚开始使用 gnu-cpp,需要一些帮助。我在阅读和自学时遇到了歧义错误我遇到了这样一个想法,即 class 的静态方法也应该受到歧义钻石问题的影响,但是 运行 下面的代码没有错误。谁能解释一下为什么?

#include<iostream>
using namespace std;
class Base
{
  public:
  static void display(){cout<<"Static";}
};
class Derived1 : public Base {};
class Derived2 : public Base {};
class Child : public Derived1, Derived2 {};
int main(void)
{
  Child obj;
  obj.display();
}

感谢您的帮助和时间。

是的。它是继承的,因为 它是 class 成员

没有歧义,因为用 obj.display() 调用的只是只有 1 个候选人可供选择,最终 "source" Base::display().

但是,此代码会产生错误:

class SuperBase {
    public:
    static void hello() { cout << "Super Base" << endl; }
};

class Base1 : public SuperBase {
    public:
    static void foo() { cout << "Base 1" << endl; }
};

class Base2 : public SuperBase {
    public:
    static void foo() { cout << "Base 2" << endl; }
};

class Derived : public Base1, public Base2 {
};

Derived obj;
obj.foo();  // Error: ambiguous resolution
obj.hello();  // No error here

根据查找规则没问题。您会看到,当您编写成员访问权限 (obj.display();) 时,不仅会在 class 及其基础 class 范围内查找成员 display。基础 class sub-objects 也被考虑在内。

如果要查找的成员 不是 静态的,因为基础 class sub-objects 是考虑的一部分,并且您有两个 sub-objects相同类型,查找时有歧义。

但是当它们静态时,就没有歧义了。为了清楚起见,C++ 标准在描述 class 成员查找时甚至有一个 (non-normative) 示例(在 [class.member.lookup] 部分):

[ Note: A static member, a nested type or an enumerator defined in a base class T can unambiguously be found even if an object has more than one base class subobject of type T. Two base class subobjects share the non-static member subobjects of their common virtual base classes.  — end note ] [ Example:

struct V {
  int v;
};
struct A {
  int a;
  static int   s;
  enum { e };
};
struct B : A, virtual V { };
struct C : A, virtual V { };
struct D : B, C { };

void f(D* pd) {
  pd->v++;          // OK: only one v (virtual)
  pd->s++;          // OK: only one s (static)
  int i = pd->e;    // OK: only one e (enumerator)
  pd->a++;          // error, ambiguous: two as in D
}

 — end example ]

通过Derived1得到的Base::display和通过Derived2得到的Base::Display实际上是同一个函数。没有要考虑的对象上下文(因为它们是静态的),这里没有歧义。