【问题标题】:Stop C++ Class Instantiation停止 C++ 类实例化
【发布时间】:2011-05-27 09:45:09
【问题描述】:

如果实例化出现错误,有没有办法停止 C++ 类?就像,返回 NULL 也许?基本上我有一个MySQL的包装类,构造函数进行连接,但是如果连接失败,我希望这个对象,嗯,没用?

PDB::PDB(string _DB_IP, string _DB_USER, string _DB_PASS, string _DB_DB)
  : _DB_IP( _DB_IP ), _DB_USER( _DB_USER ), _DB_PASS( _DB_PASS ), _DB_DB( _DB_DB )
{
  mysql_init(&this->mysql);

  this->connection = mysql_real_connect(&this->mysql, this->_DB_IP.c_str(), this->_DB_USER.c_str(), this->_DB_PASS.c_str(), this->_DB_DB.c_str(), 0, 0, 0);

  if( this->connection == NULL ) // WHAT SHOULD I DO HERE, OTHER THAN THROW AN ERROR?
    {
      cout << mysql_error(&this->mysql) << endl;
    }

  this->result = NULL;
}

在 NULL 测试中我应该做什么,停止创建等?

【问题讨论】:

  • 也许我应该将连接移出构造?或者如果 this->connection 为空,则在查询函数中抛出错误?嗯
  • 这是一个很好的标语穿在T恤上。

标签: c++ class object constructor instantiation


【解决方案1】:

抛出异常实际上是在构造过程中指示错误的唯一方法。

http://www.parashift.com/c++-faq-lite/exceptions.html#faq-17.8

【讨论】:

  • 嗯,不是的。例如,std::fstream 对象不会以这种方式指示错误。
  • 因为std::fstream 不表示构造函数中的错误。
  • @unquiet mind:是的,这是链接文章中提到的“僵尸”技术的一个示例。正如 Marshall Cline 所说,有时它可能是“最不坏”的选择,但你必须提出一个很好的论据来说服我它比投掷更好。
  • @Fred 我认为 FILE STREAMS 的一个很好的论点是标准库就是这样做的,而且效果很好。我认为使用这样的流比使用抛出异常的流要容易得多。
  • @unquiet mind:实际上 IO 错误通常不会被注意到(尤其是新手,他们不明白为什么如果输入格式错误,他们的代码会进入无限循环),因为默认情况下 iostream 不会t 抛出任何错误。
【解决方案2】:

如果连接正常失败,请在对象中设置一个标志并为该类提供一个 is_connected() 成员函数,并在您的应用程序代码中使用它。如果它通常不会失败,则抛出异常。前者是 C++ 标准库用于打开文件流的模式。

【讨论】:

  • 谨防使用诸如“通常”或“异常情况”(这两个术语彼此相反)之类的术语(未定义它们)来描述异常使用的解释。上面的文字可以理解为支持或不支持使用异常的立场(取决于读者对异常使用和什么是“正常”的现有偏好),因此它确实无助于回答问题。
  • @Fred 它确实回答了这个问题——有时你使用异常,有时你不使用。
  • 还值得一提的是,异常不是很便携,尤其是跨库边界。例如,Mozilla C++ Portability Guide 完全禁止使用异常。因此,有时您唯一的选择就是 isValid 标志,无论它是“正常”还是“异常情况”。
  • “有时使用异常,有时不使用”有何帮助?对此的明显回应是“呃,这就是我问的原因”,因为它只是重申了这个问题。给定“你想要茶还是咖啡?”,句法上有效的答案是“是”,但由于我上面指出的基本相同的原因,它仍然没有帮助。
猜你喜欢
  • 1970-01-01
  • 2016-03-19
  • 2019-04-06
  • 2018-09-27
  • 2021-05-11
  • 1970-01-01
  • 2015-06-09
  • 1970-01-01
  • 2010-09-07
相关资源
最近更新 更多