Двойное двоеточие C ++ используется после имени класса вместо пространства имен - PullRequest
2 голосов
/ 01 июля 2019

Я пытаюсь понять программу на С ++, перечисленную здесь .Меня смущает второе использование двойных двоеточий в строках 86-87:

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

Похоже, TransformType - это пользовательский тип.Как можно использовать его до New()?Я слышал, что двойное двоеточие должно использоваться после пространства имен, но здесь TransformType является типом (а именно классом), а не пространством имен.Может кто-то уточнить --- следует ли использовать двойное двоеточие после пространства имен в C ++?Можно ли вместо этого использовать точку (как в Java)?

1 Ответ

5 голосов
/ 01 июля 2019

Вы используете оператор разрешения области действия (::) для именования чего-либо в пространстве имен, в классе или в перечислении с областью видимости;это называется квалифицированный поиск .

#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 членам классов с именем типа, за которым следует ., точно так же, как вы получите доступ к не static членам классов с именем объекта, за которым следует ..C ++ не является одним из этих языков.

Кстати, это законно:

#include <iostream>

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

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

Добавление разрешения области действия к x здесь не является необходимым, поскольку язык уже знает изobj. что вы просите члена класса C.Но вы все равно можете добавить его, если хотите.В данном случае это просто «сделано для вас».

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...