Есть ли лучший способ ввести имена в область видимости класса, кроме их определения по умолчанию? - PullRequest
1 голос
/ 14 декабря 2009

Я продолжаю сталкиваться с этой проблемой:

class CCreateShortcutTask : public CTask
{
public:
    CCreateShortcutTask(
        CFilename                         filename,     // shortcut to create (or overwrite)
        Toolbox::Windows::CShellLinkInfo  definition        // shortcut definition
    ) 
    ...

Необходимость разобрать Toolbox :: Windows :: CShellLinkInfo кажется мне весьма сомнительной. Это в заголовке, поэтому я, конечно, не хочу выдавать , используя объявление пространства имен , или я буду перетаскивать это пространство имен в каждый файл клиента, который включает этот заголовок.

Но я не хочу серьезно называть эти вещи в самом интерфейсе класса. Я бы очень хотел иметь возможность сделать что-то вроде:

class CCreateShortcutTask : public CTask
{
    using namespace Toolbox::Windows;
    -or possibly-
    using Toolbox::Windows::CShellLinkInfo;

public:
    CCreateShortcutTask(
        CFilename       filename,       // shortcut to create (or overwrite)
        CShellLinkInfo  definition      // shortcut definition
    ) 
    ...

Но, похоже, это нелегальные конструкции.

Есть идеи, как этого добиться?

РЕДАКТИРОВАТЬ: Я задал более широкую версию этого вопроса здесь

Ответы [ 2 ]

7 голосов
/ 14 декабря 2009

Я думаю, что есть путаница с typedefs.

Использование приватных typedefs идеально подходит (и часто используется). Это зависит от того факта, что в C ++ typedef вводит не новый тип, а синоним!

namespace VeryLongNamespaceYoullNeverWantToSeeAgain
{
  class SuchAStupidNameShouldBeBanned
  {
  public:
    typedef xxx iterator;
    typedef zzz value_type;

    static std::string Print(value_type);
  private:
  };

  void destroy(SuchAStupidNameShouldBeBanned&);
}

namespace short
{
  class MyStruct
  {
    typedef VeryLongNamespaceYoullNeverWantToSeeAgain::SuchAStupidNameShouldBeBanned Stupid;
  public:
    void destroyStupid()
    {
      Stupid::iterator it = m_stupid.begin(), end = m_stupid.end();

      std::cout << "Getting rid of ";
      for (; it != end; ++it) std::cout << Stupid::Print(*it) << " ";
      std::cout << std::endl;

      destroy(m_stupid);
    }

  private:
    Stupid m_stupid;
  };
}

Таким образом, частные определения типов не беспокоятся:

  • поиск имени: destroy правильно вызывается
  • использование внутренних typedefs: iterator найдено
  • использование статических методов: Print найдено

Так что вы действительно можете использовать их без особых суеты. Более того, они не загрязняют глобальное пространство, поскольку они являются внутренними для класса и, хотя видимым не могут манипулировать клиентом напрямую, поэтому он не полагается на них.

В исходном файле вы можете использовать псевдонимы пространства имен и директивы (не используйте пространства имен, пожалуйста) более свободно, так что это меньше проблем.

3 голосов
/ 14 декабря 2009

Возможно, псевдоним пространства имен поможет вам в некотором роде. Вы можете написать следующее:

namespace TW = Toolbox::Windows; // define short name

class CCreateShortcutTask : public CTask
{
public:
    CCreateShortcutTask(
        CFilename           filename,
        TW::CShellLinkInfo  definition
    ) 
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...