简体   繁体   English

C ++静态成员方法调用类实例

[英]C++ Static member method call on class instance

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)上编译很好:控制台只显示“TEST IT!”。

As far as I know, static member methods shouldn't be called on instanced object. 据我所知,不应该在instanced对象上调用静态成员方法。

  1. Am I wrong? 我错了吗? Is this code correct from the standard point of view? 从标准角度来看,这段代码是否正确?
  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? 我找不到为什么会被允许,或者可能是为了帮助在模板中使用“静态或非”方法?

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; 可以使用qualified-id表达式X :: s来引用类X的静态成员; it is not necessary to use the class member access syntax (5.2.5) to refer to a static member. 没有必要使用类成员访问语法(5.2.5)来引用静态成员。 A static member may be referred to using the class member access syntax, in which case the object-expression is evaluated. 可以使用类成员访问语法来引用静态成员,在这种情况下,评估对象表达式。

class process {
public:
   static void reschedule();
};

process& g();

void f()
{
   process::reschedule(); // OK: no object necessary             
   g().reschedule(); // g() is called
}

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指针放在堆栈中,因为静态函数不需要它。

2) If it's correct, why is that? 2)如果它是正确的,那为什么? I can't find why it would be allowed, or maybe it's to help using "static or not" method in templates? 我找不到为什么会被允许,或者可能是为了帮助在模板中使用“静态或非”方法?

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 data [你建议的模板中的“静态或非静态”方法:]当可以为模板指定了许多类型,然后模板想要调用成员:提供静态函数的类型可以使用相同的表示法调用作为成员函数 - 前者可能更有效(没有this指针传递/绑定),而后者允许多态( virtual )调度和使用成员数据

  • minimising 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 updated 如果某个函数从需要特定于实例的数据演变为不需要它 - 并因此被设置为static以允许轻松实例化并防止意外使用实例数据 - 现有客户端使用的所有点都不需要进行大量更新

    • if the type's changed the var.f() invocation continues to use the var type's function, whereas Type::f() may need manual correction 如果类型改变了var.f()调用继续使用var类型的函数,而Type::f()可能需要手动修正

  • when you have an expression or function call returning a value and want to invoke the (potentially or always) static function, the . 当你有一个表达式或函数调用返回一个值并想要调用(可能或总是) static函数时, . notation may prevent you needing to use decltype or a supporting template to get access to the type, just so you can use the :: notation 符号可能会阻止您需要使用decltype或支持模板来访问该类型,这样您就可以使用:: notation

  • sometimes the variable name is just much shorter, more convenient, or named in a more self-documenting way 有时变量名称更短,更方便,或以更自我记录的方式命名

static methods can be called also using an object of the class, just like it can be done in Java. 静态方法也可以使用类的对象来调用,就像可以在Java中完成一样。 Nevertheless, you shouldn't do this. 不过,你不应该这样做。 Use the scope operator like Test::DoCrash(); 使用范围运算符,如Test::DoCrash(); Maybe you think of namespaces: 也许您会想到命名空间:

namespace Test {
    void DoCrash() {
        std::cout << "Crashed!!" << std::endl;
    }
};

which can only be called by Test::DoCrash(); 只能通过Test::DoCrash();调用Test::DoCrash(); from outside that namespace if the function is not imported explicitly using a using directive/declaration into the scope of the caller. 如果函数未使用using directive/declaration明显式导入调用者的作用域,则从该命名空间外部。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM