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

时间:2008-11-28 11:33:45

标签: c++ visual-c++ standards

这是一个小测试程序:

#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;
}

在VS2008 + SP1(vc9)上编译很好:控制台只显示“TEST IT!”。

据我所知,不应该在instanced对象上调用静态成员方法。

  1. 我错了吗?从标准的角度来看,这段代码是否正确?
  2. 如果这是正确的,那为什么?我找不到为什么会被允许,或者可能是为了帮助在模板中使用“静态或非”方法?

4 个答案:

答案 0 :(得分:60)

标准声明没有必要通过实例调用方法,这并不意味着你不能这样做。甚至有一个使用它的例子:

C ++ 03,9.4静态成员

  

可以使用。来引用类X的静态成员   qualified-id表达式X :: s;它是   没必要使用类成员访问语法(5.2.5)来引用   到静态成员。静态成员   可以              使用类成员访问语法引用,其中   case的表达式是   评价。

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

process& g();

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

答案 1 :(得分:11)

静态函数不需要被调用的实例化对象,所以

k.DoCrash();

表现与

完全相同
Test::DoCrash();

使用范围解析运算符(::)来确定类中的静态函数。

请注意,在这两种情况下,编译器都不会将this指针放在堆栈中,因为静态函数不需要它。

答案 2 :(得分:3)

  

2)如果这是正确的,那为什么?我找不到为什么会被允许,或者可能是为了帮助在模板中使用“静态或非”方法?

它在以下几种情况下可能有用:

  • [你建议的模板中的“静态或非静态”方法:] 当可以为模板指定了许多类型时,然后模板想要调用该成员:提供静态函数的类型可以使用与成员函数相同的符号来调用 - 前者可能更有效(没有this指向传递/绑定的指针),而后者允许多态(virtual)发送和使用会员数据

  • 尽量减少代码维护

    • 如果某个函数从需要特定于实例的数据发展到不需要它 - 并因此使static允许轻松实例化并防止意外使用实例数据 - 所有现有点客户端使用不需要进行大量更新

    • 如果类型已更改var.f()调用继续使用var类型的功能,而Type::f()可能需要手动更正

  • 当你有一个表达式或函数调用返回一个值并希望调用(可能或总是)static函数时,.表示法可能会阻止你需要使用{{1或者一个支持模板来访问该类型,这样您就可以使用decltype表示法

  • 有时变量名称更短,更方便,或以更自我记录的方式命名

答案 3 :(得分:2)

也可以使用类的对象调用静态方法,就像可以在Java中完成一样。不过,你不应该这样做。使用范围运算符,如Test::DoCrash();也许您会想到命名空间:

namespace Test {
    void DoCrash() {
        std::cout << "Crashed!!" << std::endl;
    }
};
如果函数没有使用Test::DoCrash();显式导入到调用者的范围内,那么

只能由using directive/declaration从该命名空间外部调用。