【问题标题】::: versus . for member functions (C++):: 相对 。对于成员函数 (C++)
【发布时间】:2014-06-06 06:15:29
【问题描述】:

我知道,给定一个类,比如 std::array,它有一个成员函数,比如 size(),我们可以通过“.”调用该成员函数,也就是说,在下面的代码中,

array<int,5> myarray;
int s=myarray.size();

s 将是表示 myarray 大小的整数。当命名空间运算符“::”也可以调用成员函数时,就会发生棘手的事情。比如我知道下面这行代码是有效的:

auto t=chrono::high_resolution_clock::now();

那么,使用我们最初用于数组的语法有什么问题?

chrono::high_resolution_clock myclock;
auto t=myclock.now();

【问题讨论】:

标签: c++ oop


【解决方案1】:

now() 是一个static 成员函数。这意味着函数本身没有隐藏的this 指针。相反,它就像一个常规函数——只是类的一部分,以避免名称冲突。

(在您的示例中,high_resolution_clock 是一个类,chrono 是一个命名空间。两者都使用 :: 表示“我想要来自 {namespace, class} 内部的东西)

【讨论】:

  • 也许这又引发了另一个问题:在std::array&lt;T, Size&gt;这个特殊的情况下,为什么size()不是一个静态成员函数?
  • 因为 STL 的设计者希望它与例如 std::vector 正交。
【解决方案2】:

简单来说,:: 将姓名与姓氏分开,而. 将组件与子组件分开。 (请注意,在 C#、Java、D 等许多语言中,没有这种区别)

在您的第一个示例中,myarray 是一个变量,其 size() 方法引用该特定变量。

array<int,5> myarray_a, myarray_b;
int sa=myarray_a.size();
int sb=myarray_b.size();

将分别给出myarray_ab 的大小(不是array&lt;int,5&gt;,即使-由于这种特殊情况-所有大小都是5)

在第二个示例中,now() 是 chrono::high_resolution_clock 类的 static 方法。

您是否拥有chrono::high_resolution_clock 类型的变量(以及数量)并不重要。该函数不引用该变量,但对所有相同类型的变量的工作方式相同(概念上只有一个now,无论您向谁询问)。

因此,调用now() 作为变量的一部分,通过完全限定其名称是相同的。

请注意,std::arraysize() 函数奇怪std::array 的大小是编译时定义的,因此 size() 也可以是静态的。但是std:: 设计师让他们作为成员(尽管constexpr,因此仍可用于编译时表达式)以保留与std::array 或其他容器相同的行为(它必须是动态的,并且与变量相关联,因为每个大小在执行过程中可能会有所不同)

【讨论】:

    【解决方案3】:

    您在这里混淆了两个概念: "::" 用于命名空间,也用于调用静态方法。

    【讨论】:

    • C++ 在这里混淆了两个概念:-p
    【解决方案4】:

    您建议的语法没有任何错误。它有效。

    但是它创建了一个对象,而:: 版本不创建任何对象。创建该对象似乎没有多大意义,因为没有必要这样做来调用静态函数。所以只调用静态函数而不创建对象会更简单。

    【讨论】:

    • 这很棒。谢谢!我实际上更喜欢这种冗余,因为此时我正处于学习阶段。
    • “它创建了一个对象”?真的吗?你有那个来源吗?它是如何做到的,哪个 ctor?
    • @MSalters 如果X 是一个类,则X x;(在函数或命名空间范围内)创建x 类型的X 对象。你真的需要一个标准参考吗?
    • See it working。如果没有提供参数,则使用默认构造函数。
    • 对不起,误读了您的答案。我把它当成. 创建了一个对象,这有点令人费解。
    猜你喜欢
    • 2011-01-11
    • 1970-01-01
    • 1970-01-01
    • 2010-09-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-06-01
    相关资源
    最近更新 更多