作者热门文章
- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我的 google-fu 不允许我找到任何与此相关的信息,所以我在这里问。
我已经通过cppcheck 运行了我的c++ 代码,它报告说assert
中的某些代码调用可能有潜在的副作用。我以较小的规模重现了这个问题:
struct Obj
{
int* myInt;
Obj() : myInt( new int(3) ) {}
~Obj() { delete myInt; }
const int* getInt() const { return myInt; }
};
struct C
{
Obj* myObj;
C() : myObj( new Obj() ) {}
~C() { delete myObj; }
const Obj* getObj() const { std::cout << "const" ; return myObj; }
Obj* getObj() { std::cout << "non const" ; return myObj; }
};
int main()
{
C c;
assert( c.getObj()->getInt() ); // Outputs "non const"
return 0;
}
( Code on Coliru )
cppcheck 是对的,在这里:getObj()
使用的方法不是 const
一,它是非常量的。
目标是 1) 满足 cppcheck 和 2) 确保这些断言中没有副作用。
我如何告诉编译器使用 const
version 而不是非常量 getter?
虽然我有一种方法可以实现这一点,但我发现它很不干净,在这种情况下我宁愿使用更传统的方法来做到这一点:const_cast
基础对象。
assert( const_cast<const C&>(c).getObj()->getInt() );
最佳答案
因为 c 不是常量:
C c;
c.getObj();
执行非常量版本。在 C++17 中,您可以使用 std::as_const()
:
assert( std::as_const(c).getObj()->getInt() );
这比你建议的要好一些:
assert( const_cast<const C&>(c).getObj()->getInt() );
如果 c++17 不可用,您可以实现自己的 as_const,并在您的断言语句:
template <class T>
const T & as_const(T& obj)
{
return obj;
}
template <class T>
void as_const(const T&& obj) = delete;
并使用它:
assert(::as_const(c).getObj()->getInt() );
必须添加::前缀以避免由于 std 命名空间中对象的 ADL 而与 std::as_const 产生歧义。
关于c++ - 我如何在 'force' 断言中使用 const 访问器?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51543125/
我是一名优秀的程序员,十分优秀!