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

发布于 2024-07-09 09:20:44 字数 515 浏览 10 评论 0原文

这是一个小测试程序:

#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!”。

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

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

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!".

As far as I know, static member methods shouldn't be called on instanced object.

  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?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

自我难过 2024-07-16 09:20:44

该标准规定不需要通过实例调用该方法,但这并不意味着您不能这样做。 甚至有一个使用它的例子:

C++03, 9.4 static Members

类 X 的静态成员可以使用
限定 ID 表达式 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
}

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

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.

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

process& g();

void f()
{
   process::reschedule(); // OK: no object necessary             
   g().reschedule(); // g() is called
}
我们只是彼此的过ke 2024-07-16 09:20:44

静态函数不需要实例化对象来调用,因此

k.DoCrash();

完全相同

Test::DoCrash();

其行为与使用范围解析运算符 (::) 来确定类内的静态函数

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

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.

瘫痪情歌 2024-07-16 09:20:44

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

它在多种情况下可能很有用:

  • [您建议的模板中的“是否静态”方法:]当可以为模板指定许多类型,并且模板随后想要调用成员:提供静态函数的类型可以使用与成员函数相同的符号来调用 - 前者可能更有效(没有 this 指针来传递/绑定),而后者允许多态(虚拟)成员数据的分派和使用

  • 最小化代码维护

    • 如果一个函数从需要特定于实例的数据演变为不需要它 - 因此被设为静态以允许轻松的无实例使用并防止意外使用实例数据 - 所有现有客户端使用点无需费力更新

    • 如果类型发生更改,var.f() 调用将继续使用 var 类型的函数,而 Type::f()< /code> 可能需要手动更正


  • 当您有一个返回 a 的表达式或函数调用时值并且想要调用(可能或总是)static 函数,. 表示法可能会阻止您使用 decltype 或支持模板来访问该类型,这样

  • 有时变量名只是更短、更方便,或者以更自记录的方式命名

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?

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

  • 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

    • if the type's changed the var.f() invocation continues to use the var type's function, whereas Type::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 use decltype or a supporting template to get access to the type, just so you can use the :: notation

  • sometimes the variable name is just much shorter, more convenient, or named in a more self-documenting way

安静被遗忘 2024-07-16 09:20:44

静态方法也可以使用类的对象来调用,就像在 Java 中一样。 尽管如此,您不应该这样做。 使用作用域运算符,如 Test::DoCrash(); 也许您会想到命名空间:

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

它只能由 Test::DoCrash(); 从该命名空间外部调用,如果该函数未使用 using 指令/声明 显式导入到调用者的作用域中。

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:

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.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文