Old*_*ier 18 c++ static member-functions
可能重复:
类实例上的C++静态成员方法调用
今天我发现我长期以来的事情(我的意思是长期的,二十年),在C++中被认为是非法的,实际上是合法的.即,调用静态成员函数,就好像它属于单个对象一样.例如:
struct Foo
{
static void bar() { cout << "Whatever."; }
};
void caller()
{
Foo foo;
foo.bar(); // Legal -- what?
}
Run Code Online (Sandbox Code Playgroud)
我通常会看到静态成员函数严格使用"作用域解析语法"调用,因此:
Foo::bar();
Run Code Online (Sandbox Code Playgroud)
这是有道理的,因为静态成员函数不与类的任何特定实例相关联,因此,我们不希望一个特定的实例进行语法"连接到"函数调用.
然而我今天发现GCC 4.2,GCC 4.7.1和Clang 3.1(作为编译器的随机抽样)接受前一种语法,以及:
Foo* foo = new Foo;
foo->bar();
Run Code Online (Sandbox Code Playgroud)
在我的具体情况,该表达式的合法性导致运行时错误,印证了这种语法的特点是比学术更感兴趣,它有着实际的后果.
为什么C++允许调用静态成员函数,就像它们是单个对象的直接成员一样 - 也就是说,通过使用.或 - >语法附加到对象实例?
Pet*_*ker 16
在C++的设计和演变(第288页)中,Bjarne Stroustrup提到在静态成员函数之前的几天,程序员使用hacks喜欢((X*)0)->f()
调用不需要对象的成员函数.我的猜测是,当静态成员函数加入到语言,通过访问->
被允许使用这样的代码的程序员可以改变f
到static
无需追捕并改变每个使用它.
据推测,你可以在你可能不知道类的东西的地方调用它,但是编译器会这样做.
假设我有一堆类,每个类都有一个返回类名的静态成员:
class Foo
{
static const char* ClassName() { return "Foo"; }
};
class Bar
{
static const char* ClassName() { return "Bar"; }
};
Run Code Online (Sandbox Code Playgroud)
然后在我的代码中,我可以做以下事情:
Foo foo;
printf( "This is a %s\n", foo.ClassName() );
Run Code Online (Sandbox Code Playgroud)
无需担心一直知道我的对象类.例如,在编写模板时,这将非常方便.
就像这样,因为标准说的是它是如何工作的.n3290§9.4声明:
可以使用qualified-id表达式引用类X的静态成员,
X::s;
不必使用类成员访问语法(5.2.5)来引用静态成员.可以使用类成员访问语法来引用静态成员,在这种情况下,评估对象表达式.[例如:Run Code Online (Sandbox Code Playgroud)struct process { static void reschedule(); }; process& g(); void f() { process::reschedule(); // OK: no object necessary g().reschedule(); // g() is called }
最后的例子]
...还观察到不可移植的代码,例如
((x*)0)->f();
Run Code Online (Sandbox Code Playgroud)
用于模拟静态成员函数.
所以我的猜测是(基于几乎所有其他奇怪的语法事物的基本原理模式),当你只是提供类型来提供向后兼容已建立但破坏的习语时,它们允许调用静态成员函数.