通过"删除"防止实例化C ++ 11类。复制构造函数

时间:2017-07-18 23:20:29

标签: c++ c++11

我想创建一个"静态类"在C ++ 11中,即只有静态方法且不可能实例化或继承的类。 想出了以下解决方案:

class Foo final {
  public:
    static void methodA(...);
    static int methodB(...);
    Foo(const Foo&) = delete;
};

这样编译器既不会创建默认构造函数也不会创建复制构造函数。 Visual Studio的IntelliSense也证实了这一点,因为它在键入Foo(时没有提供任何构造函数自动完成。

我想知道这个解决方案是否优于"普通"将默认构造函数设为私有的方法。有没有优点/缺点?

2 个答案:

答案 0 :(得分:3)

使ctor私有化的不同之处在于,它用于较旧的C ++标准,不允许您使用= delete。执行此操作的较旧形式不是“干净”,因为它依赖链接器提供错误消息,而不是编译器。如果您的ctor是私有的且没有定义,但无论如何都要调用它(例如,在类函数中),链接器将负责中止构建过程并出现错误(因为ctor仅被声明,未定义。 )= delete表单更清晰,因为编译器现在可以直接发出错误。

然而,你在这里所追求的与名称空间非常相似。所以我建议你这样做:

namespace Foo {
    void methodA(...);
    int methodB(...);
}

这不会更改调用函数的完全限定表单。与之前一样,您使用methodA()致电Foo::methodA(),因此这应该作为替补。

如果需要,您还可以使用Foo::语句删除using。例如:

using Foo::methodA;
methodA(); // Valid call.

或仅using Foo;Foo中的所有标识符带入当前范围,而不必使用Foo::为其中任何一个添加前缀。 (通常需要注意的是关于名称空间污染。)

您无法使用静态类函数执行此操作。

答案 1 :(得分:1)

看起来你正在使用错误的工具,namespace(根据@ jamesdlin的评论)会做你想做的事情:

namespace Foo {
    void methodA(...);
    int methodB(...);
};