【问题标题】:Best way to write a constructor that could have invalid parameters编写可能具有无效参数的构造函数的最佳方法
【发布时间】:2018-11-22 13:44:51
【问题描述】:

我有一个关于用 C++ 编写可读且高效的代码的问题。

我正在使用一个构造函数创建一个用于 tcp 连接的类,该构造函数将服务器的 IP 和端口作为输入。如果例如 IP 错误,我想避免创建对象。

我的问题是:

是在失败的情况下抛出异常还是创建一个更好的 带有布尔值的包装类来检查内部对象是否是 正确创建并避免在失败时调用任何函数?

【问题讨论】:

标签: c++ code-readability


【解决方案1】:

在输入无效时抛出构造函数很好,甚至 core guidelines 推荐。

命名构造函数(即静态成员函数)是同样有效的方法,它们可以例如返回一个std::optional<YourType>(那么需要C++17)。这很明显实例化可能会失败并规避异常的缺点。这是一个小例子。

#include <optional>

class Example {
    public:
       static std::optional<Example> validateAndCreate(...);

    private:
       /* Private ctor makes usage of the above function mandatory. */
       Example(...);
};

创建方法的实现可以是

std::optional<Example> validateAndCreate(...)
{
    /* Use e.g. some utility function for validation: */
    if (isInputValid(/* Pass parameter. */))
        return Example(/* Pass parameter. */);
    else
        return std::nullopt;
}

客户端代码然后构造这样的对象:

if (const auto instance = Example::validateAndCreate())
    /* Do stuff with the instance. */
    ;
else
    std::cerr << "What now?\n";

我想这种方法更能自我记录(演员可能抛出的事实应该记录在某个地方),但也更冗长。

【讨论】:

  • 确实很有趣。只是一个问题,这是否意味着变量总是动态分配的??
  • 不,std::optional 拥有其数据并且不分配。这就像普通的返回值加上一个boolean 标志。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-12-17
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多