当前位置:  开发笔记 > 编程语言 > 正文

是否可以将const引用返回给私有成员?

如何解决《是否可以将const引用返回给私有成员?》经验,为你挑选了6个好方法。

我需要实现对私有成员容器的只读访问.如果我返回一个常量引用,是否可以const_cast它并获得对该成员的完全访问权限?使用的技术是什么?

谢谢.



1> JaredPar..:

将const引用返回给私有成员是否安全

是,只要引用的生命周期不超过返回它的对象的生命周期.如果您必须公开您不想修改的私有成员,这是一个很好的方法.它并非万无一失,但它是用C++实现这一目标的更好方法之一

是否可以使用const_cast来实际处理成员

是的,没有什么可以阻止这一点.没有办法阻止某人随时在C++中丢弃const.这是C++的限制/特性.

一般来说,你应该将const_cast的每次使用标记为bug,除非它包含足够详细的评论,说明为什么它是必要的.


通过引用获得的生命周期问题与使用临时文件时遇到的问题完全不同.如果没有警告,引用可能会变为无效 暂时,你知道什么时候超出范围 - 如果你真的*密切阅读标准*!;-)

2> 小智..:

在许多情况下返回const&是一件明智的事情,特别是如果返回的对象很大或无法复制.

关于const_cast,请记住C++中的"私有"访问说明符是对程序员的帮助 - 它不是一种安全措施.如果有人想要访问对象的私有成员,无论你试图做什么来阻止它,它都可以获取它们.


@DavidThornley:返回引用时,您已经放弃了封装。

3> Maurice Perr..:
const int &ref = your_object.your_function();
*(int*)&ref = 1234;


Jeez人!为什么选票呢?莫里斯所做的一切都证明了一个普通的C式演员足以"打破"常量 - 你真的认为邪恶的肇事者杰克担心关心风格问题吗?

4> David Rodríg..:

不要担心用户做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
}

虽然上面的代码是不正确的(一个定义规则被破坏,但是对于类A有两个定义),事实是对于大多数编译器,A和Alitious A的定义是二进制兼容的.代码将编译和链接,结果是外部代码可以访问您的私有属性.

既然你知道它,就不要这样做.这将是***的维持痛苦.对于使用API​​返回对象的私有部分的软件提供向后兼容性而言,微软花费了相当多的钱(共享相同公共接口但更改内部的API的新版本会破坏某些第三方应用程序代码).对于一些广泛可用的软件,提供者(在这种情况下是微软)将经历提供向后兼容性的痛苦,但是对于鲜为人知的应用程序,他们不会,并且突然之前您运行的应用程序将以各种方式失败.



5> Kaz Dragon..:

我认为Herb Sutter曾经说过应该"防范墨菲,而不是反对马基雅维利".也就是说,你应该尽一切可能防止错误地使用错误的代码,但是对于故意滥用代码的人你无能为力.

如果有人真的想要破坏你的代码,他们可以,即使它#define private public包括你的标题之前(因此创建一个ODR违规,但我离题).

所以是的,传回一个const ref很好.



6> Naveen..:

const_cast可以肯定用于获取对成员的完全访问权限.我猜你不能阻止别人,如果他们一心想在脚上射击自己.如果私有成员不重,请考虑返回该变量的副本.

推荐阅读
手机用户2502852037
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有