在不存在的对象上调用静态成员函数

时间:2017-10-25 11:02:00

标签: c++ static language-lawyer

这样的事情刚刚出现在另一个问题中,引起了我的兴趣。鉴于Foo被声明为:

struct Foo
{
     static void bar() {std::cout << "Bar!";}
};

做这样的事似乎工作得很好:

std::vector<Foo> v;
v[10].bar();

但是,这种用法实际上是合法的吗?如果bar()未声明static,该怎么办?

3 个答案:

答案 0 :(得分:9)

  

做这样的事似乎工作得很好:

这并不意味着它没问题。

请阅读与罗杰米勒有很好类比的http://c-faq.com/ansi/experiment.html

&#34;有人告诉我,在篮球比赛中,你无法控球并跑动。我得到了一个篮球并尝试了它,它运作得很好。他显然不懂篮球。&#34;

访问v[10]是未定义的行为。如果你在其上调用成员函数并不重要,即使只是访问v[10]是未定义的。 (正如评论中所指出的,即使在调用静态成员函数时也会评估对象表达式,恕我直言应该是显而易见的,因为v[10]未在未评估的上下文中使用,如sizeof(v[10])或{{ 1}})。

你不能用视图编写C ++代码&#34;这似乎工作得很好&#34;并假设这意味着程序是正确的。

答案 1 :(得分:4)

根据[class.static]/1(强调我的):

  

可以使用qualified-id引用类X的静态成员   表达式X :: s;没有必要使用类成员访问   用于引用静态成员的语法。 可以参考静态成员   使用类成员访问语法,在这种情况下使用对象   评估表达

v[10] 必须进行评估,bar是否静态无关紧要。该向量肯定会超出界限,因此它肯定是未定义的行为。

答案 2 :(得分:-3)

函数“bar”的声明都可以,两者都是合法的。 当您打算在不同文件中使用“bar”函数时,唯一的区别就出现了。 void bar()具有全局范围,意味着您可以在任何文件中使用它(存在“bar”以外的文件)

但是static void bar()将具有文件范围,这意味着您仍然可以在父文件中使用它,但不能在该文件之外使用它。

否则,两者都是正确的。