jac*_*hab 24 c++ const reference
我需要实现对私有成员容器的只读访问.如果我返回一个常量引用,是否可以const_cast它并获得对该成员的完全访问权限?使用的技术是什么?
谢谢.
Jar*_*Par 29
是,只要引用的生命周期不超过返回它的对象的生命周期.如果您必须公开您不想修改的私有成员,这是一个很好的方法.它并非万无一失,但它是用C++实现这一目标的更好方法之一
是的,没有什么可以阻止这一点.没有办法阻止某人随时在C++中丢弃const.这是C++的限制/特性.
一般来说,你应该将const_cast的每次使用标记为bug,除非它包含足够详细的评论,说明为什么它是必要的.
小智 22
在许多情况下返回const&是一件明智的事情,特别是如果返回的对象很大或无法复制.
关于const_cast,请记住C++中的"私有"访问说明符是对程序员的帮助 - 它不是一种安全措施.如果有人想要访问对象的私有成员,无论你试图做什么来阻止它,它都可以获取它们.
Mau*_*rry 11
const int &ref = your_object.your_function();
*(int*)&ref = 1234;
Run Code Online (Sandbox Code Playgroud)
不要担心用户做const_casts只是为了打破你的不变量.如果他们真的想破坏你的代码,他们可以在你没有提供内部属性的访问器的情况下.通过返回常量引用,普通用户不会错误地修改您的数据.
封装可以防止错误,而不是间谍活动恶意编码器无论如何都可以打破它,如果他们真的关心并了解环境(编译器).在编译过程中(在我所知的所有编译器中)都失去了约束.一旦编译单元转换为二进制对象,那些对象就不知道const-ness,并且可以利用它来利用它.
// a.h
class A
{
public:
A( int a ) : data_( a ) {}
int get() const { return data_; }
private:
int data_;
};
// malicious.h
class A;
void change( A& a, int new_value );
// malicious.cpp
// does not include a.h, but redefines an almost exact copy of it
class A {
public:
A( int a ) : data_( a ) {}
int get() const { return data_; }
int data_; // private removed
};
void change( A& a, int new_value )
{
a.data_ = new_value;
}
// main.cpp
#include "a.h"
#include "malicious.h"
int main()
{
A a(0);
change( a, 10 );
std::cout << a.get() << std::endl; // 10
}
Run Code Online (Sandbox Code Playgroud)
虽然上面的代码是不正确的(一个定义规则被破坏,但是对于类A有两个定义),事实是对于大多数编译器,A和Alitious A的定义是二进制兼容的.代码将编译和链接,结果是外部代码可以访问您的私有属性.
既然你知道它,就不要这样做.这将是***的维持痛苦.对于使用API返回对象的私有部分的软件提供向后兼容性而言,微软花费了相当多的钱(共享相同公共接口但更改内部的API的新版本会破坏某些第三方应用程序代码).对于一些广泛可用的软件,提供者(在这种情况下是微软)将经历提供向后兼容性的痛苦,但是对于鲜为人知的应用程序,他们不会,并且突然之前您运行的应用程序将以各种方式失败.
我认为Herb Sutter曾经说过应该"防范墨菲,而不是反对马基雅维利".也就是说,你应该尽一切可能防止错误地使用错误的代码,但是对于故意滥用代码的人你无能为力.
如果有人真的想要破坏你的代码,他们可以,即使它#define private public
包括你的标题之前(因此创建一个ODR违规,但我离题).
所以是的,传回一个const ref很好.
归档时间: |
|
查看次数: |
13528 次 |
最近记录: |