当试图使用unique_ptr
创建派生类的实例时,我得到了segmentation fault
。在此之前,我已经编写了七个派生类的每个实例化,一个接一个,代码工作正常。
当前代码如下:
typedef std::unique_ptr<Comum> ComumPtr;
ComumPtr createInstance ( string dom, map<string, string> & config, map<string, string> & config_fields )
{
ComumPtr ptr; // initialized to nullptr.
if ( dom == "voice" ) {
ptr.reset ( new Voice (config, config_fields) );
// } else if ( dom == "account" ) { // FOR OTHER DERIVED CLASSES
// ptr.reset ( new Account (config, config_fields) );
}
return ptr;
}
// At main function:
for (vector<string>::const_iterator cit = for_domain.begin(); cit != for_domain.end(); ++cit) {
const char * section (cit->c_str());
string fsn = *cit + "_fields";
const char * fields_section_name (fsn.c_str());
const char * db_section ("Database");
map <string, string> domain_config = cfg.getSectionConfig (config_file.c_str(), section);
map <string, string> domain_config_fields = cfg.getSectionConfig (config_file.c_str(), fields_section_name);
map <string, string> database_config = cfg.getSectionConfig (config_file.c_str(), db_section);
std::unique_ptr<Comum> domain = createInstance(*cit, domain_config, domain_config_fields);
domain->readDatabaseFields (database_config); // <- segmentation fault
你认为有什么原因导致这个错误吗?
function createInstance
有机会返回nullptr,您需要检查指针是否有效:
if (domain.get())
{
domain->readDatabaseFields (database_config);
}
这一行是错误:
ComumPtr ptr; // initialized to nullptr.
虽然我理解null 是如此容易,但这也是搬起石头砸自己的脚的最好方法(无论是在c++还是Java中),因为现在这个函数的任何一次使用结果都需要检查。
相反,您可以:
- 使用Null对象:方法
readDatabaseFields
将不做任何事情 - 选择抛出异常而不是返回空指针
以上选择没有一个天生就比另一个好,这在很大程度上取决于情况;但是,两者都比返回空unique_ptr
要好。
假设你选择了异常方法:
ComumPtr createInstance ( string dom, map<string, string> & config, map<string, string> & config_fields )
{
if ( dom == "voice" ) {
return ComumPtr ( new Voice (config, config_fields) );
}
if ( dom == "account" ) {
return ComumPtr ( new Account (config, config_fields) );
}
throw std::runtime_error("Unknown config field");
}