C++ 如何防止类被malloc';d、 只允许新的?

C++ 如何防止类被malloc';d、 只允许新的?,c++,malloc,new-operator,C++,Malloc,New Operator,在某些情况下,我希望强制调用构造函数,该构造函数在new中自动调用,但在malloc中不自动调用(在这种情况下,我们必须求助于新技术)。有没有办法让类只对new而不是malloc可用 编辑:编译时限制更可取(我想和往常一样)。没有办法malloc基本上是非类型化的-它只分配一个字节缓冲区,您无法阻止它,就像您无法阻止某人将非类型化指针转换为您类型的指针一样 无论如何,不要尝试! 正如Damian Conway()所说,您的代码应该防范墨菲,而不是马基雅维利:防止用户犯诚实的错误。但是,当他们故意

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


编辑:编译时限制更可取(我想和往常一样)。

没有办法<代码>malloc基本上是非类型化的-它只分配一个字节缓冲区,您无法阻止它,就像您无法阻止某人将非类型化指针转换为您类型的指针一样

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

没有办法<代码>malloc基本上是非类型化的-它只分配一个字节缓冲区,您无法阻止它,就像您无法阻止某人将非类型化指针转换为您类型的指针一样

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

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

公共标题:

struct MyInterface
{
    static MyInterface *create();
    virtual void member() = 0; 
};
专用模块:

class MyImplementation
{
public:
    MyImplementation();
    void member() override;
};

MyInterface *MyInterface::create()
{
    return new MyImplementation();
}

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

公共标题:

struct MyInterface
{
    static MyInterface *create();
    virtual void member() = 0; 
};
专用模块:

class MyImplementation
{
public:
    MyImplementation();
    void member() override;
};

MyInterface *MyInterface::create()
{
    return new MyImplementation();
}
如果需要此类限制的原因是为了防止使用类的
无效
实例,则可以引入成员变量并使用它来确定对象的构造是否正确

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;

};

如果需要此类限制的原因是为了防止使用类的
无效
实例,则可以引入成员变量并使用它来确定对象的构造是否正确

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;

};

不要认为这个答案是你应该做的,但如果真的需要,它可能会对你有用

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

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

void* malloc (size_t size)
{
   ...
   return NULL;
}
这将阻止malloc分配内存。 现在是一个更棘手的案子。正如我们所知,
新操作符
实现可以在内部使用(并且通常使用)malloc来分配一些内存块

现在,对于每个类,都必须重载new和delete操作符。内部实现需要另一个自定义malloc和免费实现,它将调用:

#include <stdlib.h>

extern void *__libc_malloc(size_t);
extern void __libc_free(void* ptr);

一般来说,我不建议这样做,但如果你真的需要它,你可以试试。还请记住,如果使用不当,处理uu libc_malloc和u libc_free可能会导致内存损坏,

不要认为这个答案是你应该做的,但如果真的需要,它可能对你有用

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

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

void* malloc (size_t size)
{
   ...
   return NULL;
}
这将阻止malloc分配内存。 现在是一个更棘手的案子。正如我们所知,
新操作符
实现可以在内部使用(并且通常使用)malloc来分配一些内存块

现在,对于每个类,都必须重载new和delete操作符。内部实现需要另一个自定义malloc和免费实现,它将调用:

#include <stdlib.h>

extern void *__libc_malloc(size_t);
extern void __libc_free(void* ptr);

一般来说,我不建议这样做,但如果你真的需要它,你可以试试。还请记住,如果使用不当,处理uu libc_malloc和u libc_free会导致内存损坏,

我看不到一种方法来阻止有人使用
malloc()
分配内存,并应用(重新解释)转换来分配指向类类型的指针。为什么使用-1?这是一个合理的问题,对吗?仅仅因为它不可实现并不值得-1。问题有点离题:除非调用构造函数,否则类中没有对象。您可以将某些数据重新解释为类的对象,但如果这样做,您就处于UB领域。如果要创建
malloc()
backed对象,则必须使用构造函数调用进行后续操作:
void*backing=malloc(sizeof(*myObject));MyClass*myObject=新(支持)MyClass(…)注意,这使用placement
new()
操作符调用构造函数。在C++中,没有简单的< <代码> MyClass <代码>对象,没有构造。永远不要使用Malc而不是新的。这就是重点。因此,如果有一些愚蠢的程序C教育或解雇他们。发明棘手的代码不是一个选择。这完全不在我的问题范围之内。作为类的设计者,您可以决定类的功能并对其进行记录。你可以决定防止简单的错误,但你不能使一个类是防弹的。如果有人想使用
malloc
和placement new,这会不会导致你的课堂出现错误?如果不是,那你就是在施加压力