是否有更好的方法将名称引入类范围而不是键入它们?

时间:2009-12-14 18:02:02

标签: c++ visual-c++

我一直在讨论这个问题:

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

我必须拼出Toolbox :: Windows :: CShellLinkInfo。这是一个标题,所以我当然不希望发出 using namespace 声明,或者我会将该命名空间拖到包含此标题的每个客户端文件中。

但我并不认真地想要在类接口本身中完全命名这些东西。我真的很想能够做到这样的事情:

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
    ) 
    ...

但这些似乎是非法的结构。

任何想法如何实现这一目标?

编辑:I have asked a broader version of this question here

2 个答案:

答案 0 :(得分:7)

我认为typedef存在混淆。

使用私有typedef非常适合(并经常使用)。这取决于在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;
  };
}

因此,私有typedef不会打扰:

  • 名称查找:destroy已正确调用
  • 使用内部typedef:找到iterator
  • 使用静态方法:找到Print

所以你可以毫不费力地使用它们。此外,它们不会污染全局空间,因为它们是类的内部,虽然可见不能被客户端直接操作,因此他不依赖它们。

在源文件中,您可以更自由地使用命名空间别名和使用指令(请不要使用命名空间),因此它不是一个问题。

答案 1 :(得分:3)

也许命名空间别名会以某种方式帮助你。您可以写下以下内容:

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

class CCreateShortcutTask : public CTask
{
public:
    CCreateShortcutTask(
        CFilename           filename,
        TW::CShellLinkInfo  definition
    )