你为什么要让运营商`new`私有?

时间:2017-02-02 09:13:22

标签: c++ overloading new-operator

我使用OpenSplice DDS,在那里,几乎所有的C ++类(我使用的基本类,如果重要的话我可以提及它们)将new运算符重载为私有(到阻止用户使用它们。我不明白,为什么有人这样做?有人可以提供一些显示这种必要性的例子吗?

为什么我需要new :因为大多数这些类都没有默认构造函数,我需要在稍后的实现中通过unique_ptr初始化它们

简单的伎俩:另一方面......我很容易欺骗这个!我可以用另一个类包装这个类,并使用我想要的new,对吧?因此,我不了解动机,感觉风格不好。有人可以解释一下吗?

编辑:

只是为了澄清:提供一个很好的例子来解决这个问题是一个很好的答案。它会对所有看到new运营商变为私有的人有所帮助。

3 个答案:

答案 0 :(得分:3)

  

为什么有人[重载new运营商是私有的(以防止用户使用它们)]

大概是为了防止分配对象directly on heap(即动态地)。

  

有人可以提供一些显示这种必要性的例子吗?

我不知道有什么需要这个。查找此类决策信息的最佳来源是文档。如果没有记录,那么您可以询问开发人员。

我只能猜测。我的猜测是,设计师希望通过忘记释放动态对象,或者试图破坏或使用不存在的对象,使用户更难以犯错误。

编辑:这不是官方的,但标记为提供图书馆的公司员工的用户有commented on their forum

  

ISO C ++ API旨在使所有对象都在堆栈而不是堆上创建,因为这允许所有内存管理根据是否仍然引用对象自动发生。复制ISO C ++对象不会产生开销,因为这只会复制底层智能指针,从而导致对同一对象的两次引用。

  

因为大多数这些类没有默认构造函数,所以我需要稍后对它们进行初始化...

这并不一定意味着您需要动态分配。即使一个类可能没有默认构造函数,它仍然可能有一个合理的默认状态,可以通过将一些规范值传递给构造函数来实现(比如,nullptr)。

答案 1 :(得分:3)

许多嵌入式C ++需要保证在系统启动后不进行动态分配。航空,汽车和医疗设备行业通常都有此要求。有关此类编码标准及其背后的理性,请参阅以下链接:

答案 2 :(得分:2)

你并不需要新的。

可以禁止New强制堆栈分配对象(而不是堆分配)。考虑:

struct Point {
   int x, y;
};

Point * a = new Point{3, 5}; //sizeof(Point) in heap + sizeof(Point *) in stack.
Point b{3, 5}; //sizeof(Point), directly in the stack

因此,如果您删除operator new(在C ++ 11中,如果您想禁止它是正确的方法)或将其设为私有(在C ++ 11之前),您可以为用户强制执行协议。

禁止(但不删除)newing和构造函数的另一个原因可能是返回对象工厂的某种智能指针:

class MyClass {
private:
    MyClass();
    void * operator new(...);
public:
    static std::shared_ptr<MyClass> create() {
       //check if object in cache...
       auto c = std::make_shared<MyClass>();
       //Do more stuff maybe
       return c;
    }
};

如果需要,这将在工厂构造函数中强制执行某些操作,例如使用缓存或任何其他东西,禁止外部用户也使用new,但仍允许在类中使用new进行分配(如果删除operator new你不能再这样做了。)