2017-07-18 70 views
-2

我想在C++ 11中创建一个“静态类”,即只有静态方法并且不可能实例化或继承的类。 想出了以下解决方案:通过“删除”复制构造函数来阻止C++ 11类的实例化

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

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

我想知道这个解决方案是否以任何方式比使默认构造函数私有的“常见”方法更可取。有没有优点/缺点?

+12

为什么不使用名称空间呢? – jamesdlin

+0

是的,如果你没有使用过类功能,那么你不会创建一个类。你正在创建一个名字空间。 – tadman

+0

使构造函数保持私有状态是我们所能做的,没有delete关键字。效果是相同的,并且不生成代码。如果仅仅因为它更具可读性,我会使用新的语法。 –

回答

3

以使男星私人所不同的是,这是用于旧版C++标准,不允许您使用= delete。这样做的旧形式并不像“干净”,因为它依赖链接器提供错误消息,而不是编译器。如果你的ctor是私有的,并且没有定义,但是无论如何你都要调用它(例如,从一个类函数中),链接器将负责中止构建过程并产生一个错误(因为ctor只是声明的,没有定义。 )由于编译器现在可以直接发出错误,因此= delete表单更清洁。

但是,您在此之后的内容与命名空间非常相似。所以我建议你这样做,而不是:

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

这不会更改调用函数的完全限定的形式。像以前一样,您可以拨打methodA()Foo::methodA(),因此这应该作为一个直接替代品。

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

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

或者只是using Foo;,使从Foo所有标识符到当前范围,而无需任何前缀他们与Foo::。 (常用的警告在这里适用于名称空间污染。)

您不能使用静态类功能执行此操作。

1

看起来像您使用的是错误的工作工具,namespace(按@ jamesdlin的评论)会做你想要什么:

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