C++ C++;使用带有不变量的函数预条件或包装类?
我发现自己编写了很多函数,这些函数都是从许多前提条件开始的,然后我必须弄清楚如何处理所有无效输入,并为它们编写测试 请注意,我使用的代码库不允许抛出异常,以防异常与此问题相关C++ C++;使用带有不变量的函数预条件或包装类?,c++,design-patterns,wrapper,assertions,invariants,C++,Design Patterns,Wrapper,Assertions,Invariants,我发现自己编写了很多函数,这些函数都是从许多前提条件开始的,然后我必须弄清楚如何处理所有无效输入,并为它们编写测试 请注意,我使用的代码库不允许抛出异常,以防异常与此问题相关 我想知道是否有C++设计模式,而不是有前提条件,输入参数是通过保证不变量的包装类传递的。例如,假设我想要一个函数返回整数向量中的最大值。通常我会这样做: // Return value indicates failure. int MaxValue(const std::vector<int>& vec
我想知道是否有C++设计模式,而不是有前提条件,输入参数是通过保证不变量的包装类传递的。例如,假设我想要一个函数返回整数向量中的最大值。通常我会这样做:
// 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;
}
//返回值表示失败。
int最大值(常量标准::向量和向量,int*max_值){
if(vec.empty()){
返回退出失败;
}
*最大值=向量[0];
for(int元素:vec){
如果(元素>*最大值){
*最大值=元素;
}
}
返回退出成功;
}
但我想知道是否有这样的设计模式:
// 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;
}
模板
类NonEmptyVectorWrapper{
公众:
静态标准::唯一\u ptr
创建(常量标准::向量和非空向量){
if(非空向量.empty()){
返回std::unique_ptr(nullptr);
}
返回std::unique\u ptr(
新的非空向量包装器(非空向量);
}
常量std::vector和vector()常量{
返回非空向量;
}
私人:
//可以实施移动建造商/工厂以提高效率。
NoneEmptyVectorWrapper(const std::vector和non_empty_vector)
:非空向量(非空向量){}
常数std::向量非空向量;
};
int MaxValue(常量非空向量包装器和向量包装器){
const std::vector&non_empty_vec=vec_wrapper.vector();
int max_value=非空向量[0];
for(int元素:非空向量){
如果(元素>最大值){
最大值=元素;
}
}
返回最大值;
}
这里的主要优点是避免了函数中不必要的错误处理。这是一个更复杂的示例,其中可能有用:
// 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.
}
}
//在maybe\u empty\u vec中查找最接近整数n的值。
//返回值表示失败。
int GetValueClosestToInt(
const std::vector&可能是空的,
int n,
整数*最近值);
std::vector vector=GetRandomNonEmptyVector();
对于(int i=0;i<10000;i++){
int最近值;
int success=GetValueClosestToInt(向量、i和最近值);
如果(成功){
std::难道我不明白“不能失败”是什么意思吗?你正在为你的包装器创建一个唯一的\u ptr,它实际上可以生成一个nullptr,因此取消引用它可以取消nullptr,它将终止(segfault或类似)。也就是说,你的调用者将取消包装器和segfault。这更好吗?或者我在这里遗漏了什么?