我刚遇到一个问题,即类的构造函数需要分配内存。所以我很高兴地写了char *mem = static_cast<char*>(malloc(100*sizeof(*mem)));
。但后来我突然意识到,如果出现错误,我无法返回错误代码(我的代码中没有使用异常)。我该如何解决这个问题?
我应该添加bool initialized
成员,然后在上课后再检查,如下所示:
myClass mc;
if (!mc.initialized) {
printf("Memory allocation failed in mc's constructor\n");
exit(1);
}
谢谢,Boda Cydo。
答案 0 :(得分:9)
你应该使用new,而不是malloc。当你内存不足时,新抛出std :: bad_alloc。如果您未能分配(或由于任何其他原因导致初始化问题),则应从构造函数传播异常,因为这是阻止析构函数被调用的唯一方法。如果构造函数成功完成,则必须调用析构函数(当然,除非它已分配堆并且从未释放)。
答案 1 :(得分:5)
这就是发明的异常。另外,请使用new
代替malloc(3)
。
答案 2 :(得分:3)
如果你没有使用异常,你不应该使用构造函数(或者不应该编写可能失败的构造函数),因为正如你所注意到的,除了通过一个构造函数之外没有办法报告错误例外。您可以交替使用工厂函数并使用它来解除可能失败的位而不能
的位class myClass {
private:
char *m_malloced_buffer;
// disallow calling ctors/dtors directly
myClass(char *malloced_buffer) : m_malloced_buffer(malloced_buffer) {}
~myClass() { free(m_malloced_buffer); }
public:
static myClass *create()
{
char *buf = static_cast<char*>(malloc(100*sizeof(*mem)));
if(!buf) return NULL;
void *myClassRes = malloc(sizeof(myClass));
if(!myClassRes) return NULL;
new (myClassRes) myClass(buf); // placement new, uses existing memory to invoke the ctor
return static_cast<myClass*>(myClassRes);
}
static void destroy(myClass* val)
{
if(!val) return;
val->~myClass(); // explicitly invoke dtor
free(val); // deallocate memory
}
};
...
myClass *val = myClass::create();
if(val) { ... }
myClass::destroy(val);
在这个例子中,我使用了malloc并且可以自由地进行所有分配,你可以使用new(std :: nothrow)和删除一样容易。您必须提取每个可能失败的操作并进入工厂函数,以便您可以检查错误而不使用异常。即使在这个简单的例子中,你也可以看到这是一个巨大的痛苦。你说你在评论中得知“异常不是好的编码风格”,你的意思是你学习了(无论是通过有理由的论据和解释的指令,还是来自经验),或者有人说“例外”不是很好的编码风格“你已经接受了这个声明作为教条?
使用bool初始化成员会导致僵尸对象出现问题(请参阅http://www.parashift.com/c++-faq-lite/exceptions.html)。
答案 3 :(得分:2)
如果您使用的是C ++而不是C,那么您应该使用new而不是malloc。抛出异常可能就是你想在构造函数中做的事情。
如果您正在使用new(nothrow)但是因为您不想要异常,或者您正在使用malloc,那么您可以简单地测试为NULL返回的指针。然后,您将设置一个成员变量,指示该对象处于失败状态。这可以在标准C ++库的流类中看到。