在 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
实际上是同一个函数。没有要考虑的对象上下文(因为它们是静态的),这里没有歧义。
我刚开始使用 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
实际上是同一个函数。没有要考虑的对象上下文(因为它们是静态的),这里没有歧义。