C ++使用具有不变量的函数前提条件或包装类?

时间:2016-08-26 05:22:15

标签: c++ design-patterns wrapper assertions invariants

我发现自己编写了许多以许多前提条件开头的函数,然后我必须弄清楚如何处理所有无效输入并为它们编写测试。

请注意,我工作的代码库不允许抛出异常,以防与此问题相关。

我想知道是否有任何C ++设计模式,而不是有前置条件,输入参数通过保证不变量的包装类传递。例如,假设我想要一个函数在int的向量中返回最大值。通常我会做这样的事情:

// Return value indicates failure.
int MaxValue(const std::vector<int>& vec, int* max_value) {
    if (vec.empty()) {
        return EXIT_FAILURE;
    }
    *max_value = vec[0];
    for (int element : vec) {
        if (element > *max_value) {
            *max_value = element;
        }
    }
    return EXIT_SUCCESS;
}

但我想知道是否有设计模式可以做这样的事情:

template <class T>
class NonEmptyVectorWrapper {
  public:
    static std::unique_ptr<NonEmptyVectorWrapper>
             Create(const std::vector<T>& non_empty_vector) {
        if (non_empty_vector.empty()) {
             return std::unique_ptr<NonEmptyVectorWrapper>(nullptr);
        }
        return std::unique_ptr<NonEmptyVectorWrapper>(
            new NonEmptyVectorWrapper(non_empty_vector));
    }

    const std::vector<T>& vector() const {
        return non_empty_vector_;
    }

  private:
    // Could implement move constructor/factory for efficiency.
    NonEmptyVectorWrapper(const std::vector<T>& non_empty_vector)
            : non_empty_vector_(non_empty_vector) {}
    const std::vector<T> non_empty_vector_;
};

int MaxValue(const NonEmptyVectorWrapper<int>& vec_wrapper) {
    const std::vector<int>& non_empty_vec = vec_wrapper.vector();
    int max_value = non_empty_vec[0];
    for (int element : non_empty_vec) {
        if (element > max_value) {
            max_value = element;
        }
    }
    return max_value;
}

这里的主要功能是避免在函数中进行不必要的错误处理。一个更复杂的例子,这可能是有用的:

// Finds the value in maybe_empty_vec which is closest to integer n.
// Return value indicates failure.
int GetValueClosestToInt(
    const std::vector<int>& maybe_empty_vec,
    int n,
    int* closest_val);

std::vector<int> vector = GetRandomNonEmptyVector();
for (int i = 0; i < 10000; i++) {
    int closest_val;
    int success = GetValueClosestToInt(vector, i, &closest_val);
    if (success) {
        std::cout << closest_val;
    } else {
        // This never happens but we should handle it.
    }
}
每次浪费检查向量是否为空并检查失败,

// Returns the value in the wrapped vector closest to n.
int GetValueClosestToInt(
    const NonEmptyVectorWrapper& non_empty_vector_wrapper,
    int n);

std::unique_ptr<NonEmptyVectorWrapper> non_empty_vector_wrapper =
    NonEmptyVectorWrapper::Create(GetRandomNonEmptyVector());
for (int i = 0; i < 10000; i++) {
    std::cout << GetValueClosestToInt(*non_empty_vector_wrapper, i);
}

这不会失败并摆脱不必要的输入检查。

这种设计模式是不是一个好主意,是否有更好的方法来实现它,并且有一个名称吗?

0 个答案:

没有答案