c++ 如果你在常量成员函数中包含了异常安全,而不必在之后注解掉它,你能正确地测试该函数吗?

xdnvmnnf  于 2023-03-05  发布在  其他
关注(0)|答案(1)|浏览(86)

问题如何测试常量成员函数?

目标:

对常量下标操作符进行单元测试,得到一个通过的测试。换句话说,我可以避免写测试吗?让一个编译器抛出一个错误来证明成功,然后避免需要注解掉测试以允许对剩余的测试进行正确的编译?

我的尝试:我的理由是,如果我测试is_const〈〉::value并且为真,我可以抛出一个异常,该异常将被我的单元测试捕获,并允许测试“通过”,以失败更改下标索引位置处的元素值。
常量下标定义

#include <type_traits>

   // operator [] const
    
    template <typename T>                               
    typename Vector<T>::const_reference
    Vector<T>::operator[](size_t index) const {
        if (size_ <= index || index < 0) {
            throw std::out_of_range("Index out of range.");
        }
        if constexpr(std::is_const<std::decltype(*this)>::value) {
            throw std::runtime_error("Cannot modify elements of a const Vector.");
        }
        return array_[index];
    }

单元测试

TEST(SubScriptConst) {
    const Vector<int> myVecConst = {0,1,2,3,4,5,6,7,8};
    try {
        myVecConst[2] = 4; // This will throw an exception?
    } 
    catch (const std::exception& ex) {
        std::cout << "SUCCESS | Caught exception: " << ex.what() << std::endl;
    }
    CHECK_EQUAL(myVecConst[2], 2);
}

**显而易见。**它不起作用。我知道这是因为我不了解语言。我的假设是编译器在代码执行前检查常量的赋值并给出错误。如果我可以,我将把try块放在一个MACRO #ifdef中,仅用于测试,并仍然允许编译器在不测试时抛出错误。

hmmo2u0o

hmmo2u0o1#

如果一个类成员函数声明为const,那么它不能修改任何类数据成员,除了声明为mutable的类数据成员。
这个const行为是由编译器而不是C运行时强制执行的。因此,如果有人试图修改const成员函数中的不可变数据成员,那么这将是编译时错误,而不是运行时错误。因此,您可以跳过编写此类测试用例。
以下是在C
标准中的一些相关摘录:
[* 注1*:因此在const成员函数中,调用函数的对象通过const访问路径访问。-end note]
int s::f() const { return a; }

**s::h主体中的a++是格式错误的,因为它试图修改为其调用s::h()**的对象(的一部分)。

这在**const成员函数中是不允许的,因为this是指向const的指针;也就是说,*this具有const**类型。

相关问题