如果您不使用异常,则不应使用构造函数(或不应编写可能失败的构造函数),因为正如您所注意到的,除了通过异常之外,没有办法从构造函数报告错误。您可以交替使用工厂函数并使用它来将可能失败的位与不能失败的位分离
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 和 free 来完成所有的分配,你可以使用 new (std::nothrow) 和 delete 一样容易。您必须将每个可能失败的操作从 ctor 中提取到工厂函数中,以便您可以在不使用异常的情况下检查错误。即使在这个简单的例子中,你也可以看到这是一个巨大的颈部疼痛。你说你在评论中了解到“异常不是好的编码风格”,你的意思是你学到了(无论是通过有理由的论据和解释的指导,还是从经验中),还是有人说“异常不是好的编码风格”和你已经接受了作为教条的声明?
使用 bool 初始化成员会导致僵尸对象问题(请参阅http://www.parashift.com/c++-faq-lite/exceptions.html)。