如何防止类被错误化,只允许新类?

How do I prevent classes from being malloc'd, allowing only new?

本文关键字:许新类 何防止 错误      更新时间:2023-10-16

在某些实例中,我希望强制调用构造函数,该构造函数在new中自动调用,但在malloc中不自动调用(在这种情况下,我们必须采用placement new技术)。有没有办法让类只适用于new而不是malloc?

编辑:编译时间限制会更好(我想和往常一样)。

没有办法。malloc基本上是非类型化的——它只是分配一个字节缓冲区,你无法阻止它,就像你无法阻止某人将非类型化指针强制转换为你类型的指针一样。

无论如何,不要尝试!正如Damian Conway(可能)所说,你的代码应该防范Murphy,而不是Machiavelli:防止用户犯诚实的错误。但是,当他们故意决定破坏类型系统时,他们只能靠自己了。你的问题根本没有用例。不要在上面浪费资源。

您可以为类创建一个公共虚拟接口和一个工厂方法,并隐藏您的实现。这样,只能通过您提供的方法来创建类。

公共标头:

struct MyInterface
{
static MyInterface *create();
virtual void member() = 0; 
};

专用模块:

class MyImplementation
{
public:
MyImplementation();
void member() override;
};
MyInterface *MyInterface::create()
{
return new MyImplementation();
}

不要把这个答案视为你应该做的事情,但如果真的需要,它可能对你有用。

首先,在glibc中,malloc被定义为弱符号,这意味着它可以被应用程序或共享库覆盖。

您可以在共享库中定义自己的malloc,它实际上什么都不做(返回NULL)。然后使用CCD_ 2将其链接。

void* malloc (size_t size)
{
...
return NULL;
}

这将阻止malloc分配内存。现在有一个更棘手的案子。正如我们所知,new operator实现可以在内部使用(通常也这样做)malloc来分配一些内存块。

现在,对于每个类,都必须重载新的和删除的运算符。内部实现需要另一个自定义malloc和免费实现,它将调用:

#include <stdlib.h>
extern void *__libc_malloc(size_t);
extern void __libc_free(void* ptr);

或者类似的东西:

static void* malloc_internal(size_t s) {
// Wrapper for standard library's 'malloc'.
// The 'static' keyword forces all calls to malloc_internal() in this file to resolve
// to this functions.
void* (*origMalloc)(size_t) = dlsym(RTLD_NEXT,"__libc_malloc");
return origMalloc(s);
}

一般来说,我不建议这样做,但如果您真的需要,您可以尝试。还要记住,如果使用错误,处理__libc_malloc__libc_free可能会导致内存损坏,

如果您需要这样的限制是为了防止使用类的not valid实例,那么您可以引入一个成员变量,并使用它来确定对象是否构造正确。

class A
{
enum { SpecialValue = 123 };
public: 
A() : m_marker(SpecialValue)
bool isValid() const { return m_marker == SpecialValue; }
void doAction() { assert(isValid); ... }
private:
int m_marker;
};

或者,对于c++11或更高版本:

class A
{
public: 
A() : m_marker(true)
bool isValid() const { return m_marker; }
void doAction() { assert(isValid); ... }
private:
bool m_marker = false;
};