首页 > 解决方案 > C++ 的双冒号在类名而不是命名空间之后使用

问题描述

我正在尝试了解此处列出的 c++ 程序。我对第 86-87 行第二次使用双冒号感到困惑:

 using TransformType = itk::AffineTransform< ScalarType, Dimension >;
 TransformType::Pointer transform = TransformType::New();

它看起来像是TransformType一个用户定义的类型。以前如何使用它New()?听说双冒号要跟在命名空间后面,但是这里TransformType是一个类型(即类)而不是命名空间。有人可以澄清一下---应该在 C++ 中的命名空间之后始终使用双冒号吗?是否可以使用点(如在 Java 中)?

标签: c++syntax

解决方案


您可以使用范围解析运算符 ( ::) 来命名命名空间、类或范围枚举中的某些内容;这称为合格查找

#include <iostream>

namespace N
{
   int x = 0;
}

int main()
{
   std::cout << N::x << '\n';
}

将它与类一起使用通常意味着您指的是某个static成员,否则您通常会使用它objectInstance.member

#include <iostream>

class C
{
public:
   static int x;
}

int C::x = 0;

int main()
{
   std::cout << C::x << '\n';
}

虽然,在非静态成员函数中,仍然有 for 的用途::,例如消除同时存在于不同基中的名称之间的歧义。

class Base
{
public:
   void foo() {}
};

class Derived : public Base
{
public:
   void foo()
   {
      // Do base version (omitting Base:: will just call this one again!)
      Base::foo();

      // Now maybe do other things too
   }
};

int main()
{
   Derived obj;
   obj.foo();
}

static…或者在不需要对象上下文的情况下命名非成员:

#include <iostream>

class C
{
public:
   int x;
}

int main()
{
    std::cout << sizeof(C::x) << '\n';

    decltype(C::x) y = 42;
}

作用域枚举需要它,因为它们是作用域的;这就是他们的全部意义所在。它们不会泄漏到周围的范围内,但有自己的范围,因此您需要具体指定。

enum class E
{
   Alpha,
   Bravo,
   Charlie
};

void foo(E value) {}

int main()
{
   foo(E::Alpha);
}

某些语言允许您使用static类型名称后跟访问类的成员.,就像您static使用对象名称后跟访问类的非成员一样.。C++ 不是这些语言之一。

顺便说一句,这是合法的:

#include <iostream>

class C
{
public:
   int x = 42;
};

int main()
{
   C obj;
   std::cout << obj.C::x << '\n';
//                  ^^^ what?!
}

x没有必要在此处添加范围解析,因为该语言已经知道obj.您正在请求 class 的成员C。但如果你愿意,你仍然可以添加它。在这种情况下,它通常只是“为你完成”。


推荐阅读