提问者:小点点

我可以像使用命名空间一样使用类作用域,而不是用类名作为所有东西的前缀吗


所以在头文件中我可以

namespace X {
    doThis();
}

在实现文件中我可以

namespace X {
   doThis() { .... }
}

但如果我有课

class X {
    public:
    doThis();
};

我有可能在实现文件中做这样的事情吗

class X {
    doThis() { .... }
}

而不是x::doThis(){。。。。}


共1个答案

匿名用户

这里有一个“Java黑客”,你从类中“继承”它的成员进入你的命名空间:

class MyUserType : /*protected|private*/ X {

     void foo() {
         doThis(); // works
     }
}

当然这只适用于

  • 类不定义在继承时干扰的附加(非静态)功能
  • 调用代码位于可以从类型继承的类中
  • 派生类不是模板,因为两阶段查找再次使事情变得奇怪(尽管您可以使用使用声明逐个名称地减轻它们)

在注释中,您似乎主要对代码的简洁性有问题。 调查

免责声明:下面的示例基本上是从cppreference复制的

>

  • 内联变量(C++17),它是关于命名空间级静态变量的,也适用于类成员:

    >

  • constexpr/const静态成员初始化权限位于声明中。

    如果integral或enumeration类型的静态数据成员声明为const(而不是volatile),则可以使用初始值设定项对其进行初始化,其中每个表达式都是常量表达式,就在类定义中:

     struct X
     {
         const static int n = 1;
         const static int m{2}; // since C++11
         const static int k;
     };
     const int X::k = 3;
    

    constexpr成员甚至需要在声明中具有初始值设定项:

    struct X {
        constexpr static int arr[] = { 1, 2, 3 };        // OK
        constexpr static std::complex<double> n = {1,2}; // OK
        constexpr static int k; // Error: constexpr static requires an initializer
    };
    

    请注意,在某些情况下,您可能仍然需要类外定义,但不需要初始值设定项:

    如果ODR使用const非内联(自C++17以来)静态数据成员或constexpr静态数据成员(自C++11以来)(直到C++17²),则仍然需要命名空间范围内的定义,但它不能有初始值设定项。 可以提供一个定义,即使是多余的(自C++17以来)。

    struct X {
        static const int n = 1;
        static constexpr int m = 4;
    };
    const int *p = &X::n, *q = &X::m; // X::n and X::m are odr-used
    const int X::n;             // … so a definition is necessary
    constexpr int X::m;         // … (except for X::m in C++17)
    

    在很长一段时间里,Java都没有枚举,所以你需要在一个基类中定义静态常量,然后从它“继承”来获取常量。

    ²如果静态数据成员声明为constexpr,则它是隐式内联的,不需要在命名空间范围内重新声明。 这种不带初始值设定项的重新声明(如上面所示,以前是必需的)仍然是允许的,但不推荐使用。