我试图理解列出的here的C ++程序。我对第86-87行的双冒号的第二次使用感到困惑:
using TransformType = itk::AffineTransform< ScalarType, Dimension >;
TransformType::Pointer transform = TransformType::New();
看起来TransformType
是用户定义的类型。在New()
之前如何使用它?我听说要在名称空间后使用双冒号,但是在这里,TransformType是类型(即类)而不是名称空间。有人可以澄清---应该在C ++中的命名空间之后始终使用双冒号吗?可以使用点(例如Java)代替吗?
答案 0 :(得分:5)
您可以使用范围解析运算符(::
)在名称空间,类,范围枚举中命名;这称为qualified lookup。
#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';
}
尽管,在非静态成员函数中,::
仍然有用法,例如消除同时存在于不同基础中的名称之间的歧义。
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
的{{1}}类成员,就像您访问对象名称后跟对象名称的非.
类的成员一样static
。 C ++不是这些语言之一。
顺便说一句,这是合法的:
.
这里不必向#include <iostream>
class C
{
public:
int x = 42;
};
int main()
{
C obj;
std::cout << obj.C::x << '\n';
// ^^^ what?!
}
添加范围解析,因为该语言已经从x
得知您正在请求类obj.
的成员。但是您仍然可以根据需要添加它。在这种情况下,通常只是“为您完成”。