c++ - 如何防止在非常量对象上意外调用变异函数?

标签 c++ c++11

假设我们有一个 myType 类型的 Object obj,我们想将它传递给函数 Foo,它会返回一些关于 obj 的有值(value)的信息。函数 Bar 是声明 obj 的地方,也是从那里调用 Foo 的地方:

void Bar ()
{

myType obj; //default constructor

string valuableInfo = Foo(obj); 

//do other stuff
//...

} //end of Bar()

当然,这段代码并没有过多地说明 Foo 是否将 obj 作为引用或作为值,以及 Foo 是否以任何方式修改 obj。

当然,如果 Foo 将 obj 作为值或 const 引用,我们不会有任何问题。

string Foo (const myType & input); //this is fine 
string Foo (myType input); //so is this

但我们不能保证这一点!函数签名很可能是

string Foo (myType & input); //asking for trouble!!

但是检查我们想要传递 obj 的每个函数的签名非常不方便,那么我们如何指定我们只想将我们的对象传递给 promise 不修改它的函数呢?

当然,一种方法是将 obj 声明为 const,但这种方法的问题是我们失去了灵 active 。如果我们在调用 Foo(obj) 之后想在 Bar() 中修改 obj 怎么办?

void Bar ()
{

const myType obj; //default constructor

string valuableInfo = Foo(obj); //compiler will complain if Foo's signature doesnt match

//we can't modify obj here :(
//...

} //end of Bar()

明显但不好的解决方案是这样做:

void Bar ()
{

myType obj; //default constructor

const myType immutableObj {obj}; //copy ctr call
//this is expensive and not recommended if obj is big! want to avoid

string valuableInfo = Foo(immutableObj); //will get the valuable Info risk free
// compiler will complain if Foo has inappropriate signature

//do other stuff
//...

} //end of Bar()

那么这里最好的解决方案是什么?有没有办法静态断言 Foo 对我们传入的对象是非侵入性的?我们可以暂时将 obj 设为 const(无需创建新的 const 对象)或类似的东西吗?

最佳答案

C++17 , 感谢 P0007R1 :

foo(std::as_const(obj));

在 C++17 之前,如果你发现自己经常需要这样做,那么自己编写一个帮助程序是微不足道的:

template<class T> 
constexpr typename std::add_const<T>::type& as_const(T& t) noexcept { return t; }

// prevent accidentally creating an lvalue out of a const rvalue
template<class T> void as_const(const T&&) = delete; 

当然,您所做的任何事情都无法防止有人故意抛弃 constness。墨菲、马基雅维利等

关于c++ - 如何防止在非常量对象上意外调用变异函数?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34097504/

相关文章:

c++ - 在 reading/dev/fb0 上没有得到预期的输出

c++ - 如何在运行时实现 base 2 循环展开以进行优化

c++ - 为什么我的字符串分配会导致段错误?

c++ - 在 C++ 模板中使用 'using' 的正确做法

c++ - std::is_base_of 用于模板类

java - 是否有任何工具/软件可以从 C++ 移植到 Java

c++ - 将文件保存到目录 C++

c++ - C++ 是否仍被视为静态类型语言?

c++ - catch 站点异常的常见用法是什么?

c++11 - 使用 c++11 将对存储在 GCC 绳中