1

可能重复:
如何防止通过“新”运算符分配类?(我想确保我的 RAII 类始终分配在堆栈上。)

假设我在库中定义了一个类

class Base {};

我将课程发布给用户。

一个用户定义了一个新类

class Derived : public Base {}

问题我可以做些什么Base来防止用户Derived在堆上创建一个实例?

例如,这是允许的

Derived dd;

这不是

Derived* dd = new Derived();

谢谢,

4

3 回答 3

9

我认为你能做的最好的事情就是private operator new在你的基类中声明一个(我不记得是否需要这样做,但你可能想要同时做这三个:正常、数组和放置)。用户仍然可以通过在 Derived 类中创建自己的来解决这个问题,operator new但至少他们必须考虑它并积极努力颠覆你的意图。

如果您担心在堆上创建类时会出现非意外问题(例如子类的恶意开发人员),C++ 不是该项目的语言。它功能强大,并且有很多地方您必须依靠您的最终程序员而不是绕过意图。

于 2012-06-14T21:05:28.083 回答
4

operator new在基类中设为私有。

class Base {
    void* operator new(size_t);
};
class Derived : public Base {
}

//...

Base* p = new Derived; //ERROR
Derived d;             //OK
于 2012-06-14T21:04:11.533 回答
0

除了将new操作员设为私有之外Base,您还可以提醒用户Base其意图Base是什么。这样,使用的开发人员Base不能声称没有记录意图。

class Base
{
    void * operator new (size_t) {}
    void * operator new[] (size_t) {}
    void * operator new (size_t, void *) {}
protected:
    struct I_promise_not_to_dynamically_allocate_Base {};
    Base (I_promise_not_to_dynamically_allocate_Base) {}
    virtual ~Base () {}
    //...
};

现在,当开发人员使用 时Base,他们被迫传入参数:

class Derived : public Base
{
public:
    Derived () : Base(I_promise_not_to_dynamically_allocate_Base()) {}
    //...
};

如前所述,没有什么能阻止开发人员newdelete他们自己重载,但那样他们就会违背承诺!

于 2012-06-14T21:29:50.223 回答