C++ 类实例上的静态成员方法调用
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/325555/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
C++ Static member method call on class instance
提问by Klaim
Here is a little test program:
这是一个小测试程序:
#include <iostream>
class Test
{
public:
static void DoCrash(){ std::cout<< "TEST IT!"<< std::endl; }
};
int main()
{
Test k;
k.DoCrash(); // calling a static method like a member method...
std::system("pause");
return 0;
}
On VS2008 + SP1 (vc9) it compiles fine: the console just display "TEST IT!".
在 VS2008 + SP1 (vc9) 上它编译得很好:控制台只显示“测试它!”。
As far as I know, static member methods shouldn't be called on instanced object.
据我所知,不应在实例化对象上调用静态成员方法。
- Am I wrong? Is this code correct from the standard point of view?
- If it's correct, why is that? I can't find why it would be allowed, or maybe it's to help using "static or not" method in templates?
- 我错了吗?从标准的角度来看,这段代码是否正确?
- 如果正确,为什么会这样?我不知道为什么它会被允许,或者它可能是为了帮助在模板中使用“静态与否”方法?
回答by David Rodríguez - dribeas
The standard states that it is not necessary to call the method through an instance, that does not mean that you cannot do it. There is even an example where it is used:
标准规定没有必要通过实例调用方法,这并不意味着你不能这样做。甚至还有一个使用它的例子:
C++03, 9.4 static members
C++03, 9.4 静态成员
A static member s of class X may be referred to using the qualified-id expression X::s; it is not necessary to use the class member access syntax (5.2.5) to refer to a static member. A static member may be referred to using the class member access syntax, in which case the object-expression is evaluated.
可以使用限定 ID 表达式 X::s 来引用类 X 的静态成员 s;没有必要使用类成员访问语法 (5.2.5) 来引用静态成员。可以使用类成员访问语法来引用静态成员,在这种情况下,将评估对象表达式。
class process {
public:
static void reschedule();
};
process& g();
void f()
{
process::reschedule(); // OK: no object necessary
g().reschedule(); // g() is called
}
回答by jab
Static functions doesn′t need an instanciated object for being called, so
静态函数不需要被实例化的对象被调用,所以
k.DoCrash();
behaves exactly the same as
行为与
Test::DoCrash();
using the scope resolution operator (::) to determine the static function inside the class.
使用范围解析运算符 (::) 来确定类内的静态函数。
Notice that in both case the compiler doesn′t put the this
pointer in the stack since the static function doesn't need it.
请注意,在这两种情况下,编译器都不会将this
指针放入堆栈中,因为静态函数不需要它。
回答by Tony Delroy
2) If it's correct, why is that? I can't find why it would be allowed, or maybe it's to help using "static or not" method in templates?
2)如果是正确的,为什么?我不知道为什么它会被允许,或者它可能是为了帮助在模板中使用“静态与否”方法?
It's potentially useful in several scenarios:
它在以下几种情况下可能有用:
[the '"static or not" method in templates' you suggest:]when many types could have been specified to a template, and the template then wants to invoke the member: the types providing a static function can be called using the same notation as a member function - the former may be more efficient (no
this
pointer to pass/bind), while the latter allows polymorphic (virtual
) dispatch and use of member dataminimising code maintenance
if a function evolves from needing instance-specific data to not needing it - and is therefore made
static
to allow easy instance-free use and prevent accidental use of instance data - all the points of existing client usage don't need to be labouriously updatedif the type's changed the
var.f()
invocation continues to use thevar
type's function, whereasType::f()
may need manual correction
when you have an expression or function call returning a value and want to invoke the (potentially or always)
static
function, the.
notation may prevent you needing to usedecltype
or a supporting template to get access to the type, just so you can use the::
notationsometimes the variable name is just much shorter, more convenient, or named in a more self-documenting way
[您建议的模板中的“静态或非静态”方法:]当可以为模板指定许多类型,然后模板想要调用成员时:可以使用相同的表示法调用提供静态函数的类型作为成员函数 - 前者可能更有效(没有
this
指向传递/绑定的指针),而后者允许多态 (virtual
) 分派和使用成员数据最小化代码维护
如果功能从需要特定于实例的数据演变为不需要它 - 因此
static
可以轻松地使用无实例数据并防止意外使用实例数据 - 现有客户端使用的所有点都不需要费力地更新如果类型改变了,
var.f()
调用会继续使用var
类型的函数,而Type::f()
可能需要手动更正
当您有一个表达式或函数调用返回一个值并想要调用(可能或总是)
static
函数时,该.
表示法可能会阻止您需要使用decltype
或支持模板来访问该类型,这样您就可以使用该::
表示法有时变量名更短,更方便,或者以更自我记录的方式命名
回答by Johannes Schaub - litb
static methods can be called also using an object of the class, just like it can be done in Java. Nevertheless, you shouldn't do this. Use the scope operator like Test::DoCrash();
Maybe you think of namespaces:
静态方法也可以使用类的对象来调用,就像它可以在 Java 中完成一样。然而,你不应该这样做。使用范围运算符,就像Test::DoCrash();
您可能会想到命名空间一样:
namespace Test {
void DoCrash() {
std::cout << "Crashed!!" << std::endl;
}
};
which can only be called by Test::DoCrash();
from outside that namespace if the function is not imported explicitly using a using directive/declaration
into the scope of the caller.
Test::DoCrash();
如果函数没有使用 a 显式导入using directive/declaration
到调用者的范围内,则只能从该命名空间外部调用它。