我们假设您有以下课程:
struct Foo {
static void print(std::string x) { std::cout << x << std::endl; }
};
调用print
之间有什么区别
Foo foo; //Or a pointer...
foo.print("Hello world");
和
Foo::print("Hello world");
答案 0 :(得分:6)
在打电话方面没有区别。它是六个中的六个,另外六个。
Foo::print("Hello world");
更多惯用;一个惯例已经成长,这向读者发出print
可能为static
函数的信号。为此,在您的特定情况下使用foo.print("Hello world");
是特殊的,因此令人困惑。因此,请避免这种情况,特别是如果引入不必要的实例foo
会产生开销。
请注意,如果要在复杂类层次结构中的另一个方法中达到print
的特定覆盖,也可以使用使用范围解析运算符的表示法!因此我使用上面的可能。
答案 1 :(得分:6)
第一个版本必须构建和销毁Foo
,这有明显的区别。
然后有明显的相似之处在于两个版本在执行函数调用时都会执行相同的操作(构造字符串,打印等)。
不太明显的区别在于对两个表达式的评价。你看,即使调用不需要foo
,它仍然作为表达式的一部分进行评估:
可以使用qualified-id引用类X的静态成员 表达式X :: s;没有必要使用类成员访问 用于引用静态成员的语法。 可以参考静态成员 使用类成员访问语法,在这种情况下使用对象 表达式被评估。
在你的情况下,这并不意味着什么。但在某些情况下,它可能会阻止您的程序编译。 For instance, if foo
was instead a reference parameter in a constexpr function
答案 2 :(得分:0)
你的例子没有区别。请记住,静态变量在您的类的所有实例之间共享。因此,您可以通过范围运算符或成员选择来访问它们:
class A{
public:
A(){count++;}
~A(){count--;}
static int count;
};
int A::count = 0;
int main(){
A aObj, bObj, cObj;
std::cout << "number of A instances: " << A::count << std::endl;
std::cout << "number of A instances: " << aObj.count << std::endl;
return 0;
}