在C++中删除纯静态公共接口上的复制/赋值运算符是否有意义
Does it make any sense to delete copy/assignment operators on a purely static public interface in C++?
我正在编写一个类,该类在C++中有一个公共静态方法和几个私有方法。在这种情况下,显式删除(请参阅下面的代码)复制和赋值运算符是否有意义?
public:
static MyReturnType* CreateSomeMock(const myType input);
MyClass(const MyClass&) = delete;
MyClass& operator=(const MyClass&) = delete;
private:
static ...
我倾向于说我不应该担心有人试图复制或分配给没有实例变量的默认构造类。我只是不是 100%,很好奇社区认为什么是最佳实践。
更新 1
我已将私有方法移至.cpp文件中定义的非成员函数。标头仍然包含公共成员函数CreateSomeMock
,我仍然对赋值/复制构造感到好奇 =)。
更新 2
这个"类"本质上是一个命名空间。我很欣赏围绕这一点的所有答案,并且还想在这种情况下将其保持在问题= delete
部分的主题上(我同意在这一点上确实应该避免......但我举个例子,它有时会发生)。
具有一个或多个静态函数的类与命名空间中的几个函数之间的唯一区别是使用模板时:可以将类用作模板参数,但不能用作命名空间。
或者,可以使用静态方法作为模板参数,但在向类或命名空间添加更多方法时,该参数不会缩放。
例如,如果您有:
class X {
public:
static void a();
static void b();
};
您可以在模板中将其用作some_template<X>
,并且您的模板可以在模板参数上调用 a 和 b:
template<typename T>
void some_template() { T::a(); T::b(); }
但是,如果X
是命名空间,则需要两个模板参数: some_template<X::a, X::b>
如果这是一个有效的用例,所以你确实需要一个静态类,你可能希望避免意外创建它的实例。
一个实际的原因是,在C++中,每个对象都需要大于零的大小:当有人意外创建此类的实例时,即使最小,它也会产生成本。
delete
它们不会有什么坏处,这样编译器就不会为您创建默认的。但是,您应该遵循 3 规则并显式声明析构函数(这并不重要)。
不过,这门课毫无意义。似乎您应该将非成员函数声明为命名空间的一部分:
namespace myFactoryPattern {
MyReturnType* CreateSomeMock(const myType input);
这种模式称为静态类。它与命名空间(您可以将其视为替代方法)的不同之处在于,模板可以专用于它。这是预期的,但不是必需的删除:(在类或基类中)
- 默认、复制和移动构造函数
- 复制和移动作业
或者,您也可以删除:
- 析构函数(不允许非指针和
delete
) -
operator new(size_t)
和operator new[](size_t)
(不允许new
到永远不会删除的裸指针)
后者有一个有趣的因素,让每个人都感到惊讶,并从他们的时间中窃取时间来了解正在发生的事情以及为什么他们不能创建和实例。
或者 - 您可能只允许实例。这真的没有人,有经验的程序员不会创造任何东西;但是,您仍然可以将其传递给模板函数,这些函数期望在静态方法满足所需接口的情况下传递成员。
- CRTP 中的复制赋值运算符 - gcc vs clang 和 msvc
- 为什么基类中的复制和交换会导致派生类中的复制赋值运算符被隐式删除?
- 在c++中重载复制赋值运算符
- 复制构造函数和复制赋值运算符是否应具有相同的语句?
- 移动赋值运算符与复制赋值运算符
- Gcc 使用 memcpy 作为隐式复制赋值运算符,而不是成员复制
- 如何在没有复制赋值运算符的情况下交换两个对象
- 模拟 C++ 中 lambda 的复制赋值运算符
- 重载复制赋值运算符
- 为什么C++编译器会创建复制构造函数和复制赋值运算符
- 默认的复制构造函数和复制赋值运算符给出奇怪的错误
- 重载运算符 = 返回 void 是否不可能成为复制赋值运算符
- 了解复制构造函数和复制赋值运算符
- 重载全常量类型的复制赋值运算符的正确方法是什么?
- 是具有复制和交换习惯用法的复制赋值运算符,建议进行自赋值检查
- 删除复制构造函数或复制赋值运算符算"user declared"吗?
- 为什么我们需要删除复制赋值运算符中的指针
- 重载非类型模板结构的成员结构的复制赋值运算符
- clang-libc++错误:重载解析选择了隐式删除的复制赋值运算符
- C++移动语义:为什么调用复制赋值运算符=(&)而不是移动赋值运算符=(&&)?