c++ - C++ 的双冒号在类名而不是命名空间之后使用
问题描述
我正在尝试了解此处列出的 c++ 程序。我对第 86-87 行第二次使用双冒号感到困惑:
using TransformType = itk::AffineTransform< ScalarType, Dimension >;
TransformType::Pointer transform = TransformType::New();
它看起来像是TransformType
一个用户定义的类型。以前如何使用它New()
?听说双冒号要跟在命名空间后面,但是这里TransformType是一个类型(即类)而不是命名空间。有人可以澄清一下---应该在 C++ 中的命名空间之后始终使用双冒号吗?是否可以使用点(如在 Java 中)?
解决方案
您可以使用范围解析运算符 ( ::
) 来命名命名空间、类或范围枚举中的某些内容;这称为合格查找。
#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
。但如果你愿意,你仍然可以添加它。在这种情况下,它通常只是“为你完成”。
推荐阅读
- php - 在 HTML 选择更改后将值传递给 PHP
- node.js - $lookup 与整数类型字段?
- python-3.x - 如果满足条件,则将行值替换为另一列中的行值
- javascript - 根据年、月和日计算使用 Bootstrap Datepicker 设置的两个日期之间的差异
- mongodb - MongoDb:删除另一个数组中数组的索引
- c++ - 标准::向量
分配有 (n,0) 是不可迭代的 - python-3.x - Python 和 SQLite3:如何写入比表中的列少的值
- scala - 在 Scala 中添加两个地图的复杂性
- windows - 当我尝试启动 tomcat 服务器时,Docker 在构建期间挂起
- c++ - ld 忽略其他路径