【问题标题】:Using-directive class static functions?使用指令类静态函数?
【发布时间】:2011-05-21 17:00:00
【问题描述】:

我使用的 API 在名为 TCODConsole 的类中具有 很多 函数作为静态函数。现在我以为它在一个命名空间中,所以我写了:using namespace TCODConsole;。然后我发现TCODConsole 不是命名空间,而是一个类。

有没有办法像使用using namespace 一样导入这些函数?

【问题讨论】:

  • 您是在询问将TCODConsole 类保留在命名空间中吗?
  • 他想做类似的事情:class A { ... static void foo ... };使用命名空间 A; /* 这里是问题 */ ... int main() { foo() ; }

标签: c++ class namespaces


【解决方案1】:

不,没有快捷方式可以调用myStaticFun() 而不是MyClass::myStaticFun()。你不能在课堂上做到这一点。它是一个类,而不是命名空间。但是您可以编写类似包装器的东西。也就是说,您将添加具有相同名称的函数并从该函数调用静态方法。像这样的:

class MyClass {
    static void fun();
};

void fun() {
    MyClass::fun();
}

// call it
fun();

不是一个很好的方法。就个人而言,我认为最好坚持上课而不是这样做。

【讨论】:

  • 我会在 fun() 之前添加 inline 关键字,以确保它确实被内联(或至少提高它被内联的机会)。
  • @Boaz Yaniv,我的回答只是一种解决方法的想法。没有考虑内联或污染全局命名空间等。我同意这不是一个很好的方法,很多事情都可能出错。
  • 我想我会联系库的作者,然后询问他下次进行非向后兼容升级时是否可以使用命名空间而不是具有静态函数的类。
【解决方案2】:

虽然我可能误解了这个问题, 如果缩短资格是目标, typedefing 像下面这样符合目的吗?

struct TCODConsole {
  static void f();
  static void g();
};

int main() {
  typedef TCODConsole T;
  T::f();
  T::g();
}

或者,如果类TCODConsole可以被实例化, 因为static 成员函数可以用相同的形式调用 非静态成员函数,下面的代码可能达到目的:

int main() {
  TCODConsole t;
  t.f();
  t.g();
}

【讨论】:

    【解决方案3】:

    我想不出一个干净的方法来做到这一点,但我可以想到一个有点丑陋的黑客,只要使用它的代码是类的一部分(如果 TCODConsole 真的包含 只有静态成员函数)。假设您是bar(),是Foo 类的成员函数,并且您想调用一个函数baz(),它是TCODConsole 的静态成员,但没有完全限定它。你可以做的是从 TCODConsole 私下派生 Foo:

    class Foo : private TCODConsole
    {
        void bar()
        {
            baz();
        }
    
    };
    

    是的,这很难看。 :(

    如果您想使用 Boost.PP(Boost 预处理器宏库 - 您无需编译或包含 Boost 中的任何其他内容即可使用它),您可能可以制作一个不那么难看但更复杂的宏这将为您“导入”这些函数,方法是将它们用内联函数包装在另一个命名空间中(然后您可以随意导入)。它仍然需要您明确指定要“导入”的每个函数的名称,因此您的代码(减去宏)将如下所示:

    namespace TCODStatic
    {
        IMPORT_FROM_TCOD(foo)
        IMPORT_FROM_TCOD(bar)
        IMPORT_FROM_TCOD(baz)
        IMPORT_FROM_TCOD(spaz)
    }
    

    然后你就可以在任何你想写的地方写using namespace TCODStatic;

    【讨论】:

      【解决方案4】:

      简短的回答:不是不使用宏。 C++ 语言中没有适当的机制来做这样的事情:

      class A
      {
      public:
        static void foo();
      };
      
      // ...
      
      using A;
      foo();
      

      您可以使用宏为您构建这些表达式:

      #define FOO() (A::foo())
      
      FOO();
      

      但我不鼓励这样做,因为如果您大量使用此类宏,它可能会成为维护的噩梦。你最终会得到这样的代码:

      FOO();
      BAR();
      SUPERGIZMO(a, b, c);
      

      ...在程序中的任何地方,这些东西都没有被定义为一流的名称。你已经失去了所有类型检查,代码使用了只有你知道的“秘密语言”,并且变得难以调试、扩展和修复。

      编辑:

      你可以写一种桥梁。像这样:

      class FooBar
      {
      public: 
        static void gizmo();
      };
      
      namespace Foo
      {
        void gizmo() { FooBar::gizmo(); };
      };
      
      using namespace Foo;
      
      gizmo();
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2021-01-24
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2011-11-21
        • 1970-01-01
        • 1970-01-01
        • 2012-12-28
        相关资源
        最近更新 更多