程序的输出是什么?改变了我对const应用的看法,可以改变const引用所指对象的值。

pengzhenwanli 2003-08-20 06:20:29
以下下仅仅是测试,只考虑更改的问题,
#include <iostream>
using namespace std;
class Test
{
public:
Test():a(new int(1)) { }
~Test()
{
delete a;
}
int *a;
};

void Message( const Test &t )
{
cout << ++*t.a << endl;
}

int main()
{
//Handle handle1;
//Handle handle2;
//handle1 = handle2;
Test test;
Message( test );
cout << *test.a << endl;
}
...全文
79 22 打赏 收藏 转发到动态 举报
写回复
用AI写文章
22 条回复
切换为时间正序
请发表友善的回复…
发表回复
lyr311 2003-12-16
  • 打赏
  • 举报
回复
Mark!
pengzhenwanli 2003-08-25
  • 打赏
  • 举报
回复
没有人再来说一下?
cwanter 2003-08-23
  • 打赏
  • 举报
回复
const只是C++编译器实现的一种机制~
pengzhenwanli 2003-08-23
  • 打赏
  • 举报
回复
我知道不奇怪。
按照定义你们是怎样使用const的引用?我想大多数人都不会这么用吧!
wbh0360 2003-08-23
  • 打赏
  • 举报
回复
t的成员没有改变啊,只是t成员指向的哪个内存的内容变了!
不奇怪!
ck_chuyun 2003-08-23
  • 打赏
  • 举报
回复
http://www.cstc.net.cn/docs/docs.php?id=89
给你看篇文章
aflyinghorse 2003-08-22
  • 打赏
  • 举报
回复
我认为这是一个引用计数的不错的例子
记得The C++ Programing Language中string类
的例子也有类似代码,关于修改参数的const引用
内部的指针的内容,我觉得没有什么不一致问题
毕竟修改的是堆内存中的整数值,而类中只是存储一个
指针值,并且通过指针间接的操纵那个整数。所以const引用
和修改那个整数值没什么关系。
jyfcsdn 2003-08-22
  • 打赏
  • 举报
回复
从C++语言本身来说,他本来就被设计成能够处理各种实际的问题的高效工具,所以提供如此灵活性:它的编译器没有限制你,使你在编译层面就不能够修改const变量的成员指针所指向的内容。正是由于这种灵活性才允许Koenig使用如此的实现技术来实做出这样的计数类。

不过,正是由于这种灵活性带来的不确定性,进而带来的复杂性,使得没有意识到存在这种问题的人员很容易误用这种手法,编出的代码就有错了。所以,我一般不会这样来改变const对象成员指针所指的内容。绝大多数情况下,我都不会使用这种可能引起不一致性问题的灵活技术。

为了健壮,为了稳定,只能舍弃一定的灵活了。

谨慎使用!
pengzhenwanli 2003-08-22
  • 打赏
  • 举报
回复
#include <iostream>
#include <string>
using namespace std;
class Handle;
class UseCount;
class Show
{
public:
Show(const char *Name):m_strName(Name)
{
cout << m_strName << " Show::Show() constructor" << endl;
}
~Show()
{
cout << m_strName <<" Show::~Show() destructor" << endl;
}
private:
string m_strName;

};
class UseCount
{
public:
UseCount():m_pnUse(new int(1)) { }
UseCount( const UseCount & use): m_pnUse(use.m_pnUse) { ++*m_pnUse; }
~UseCount()
{
if(--*m_pnUse == 0 )
delete m_pnUse;
}

bool reattach( const UseCount &u )
{
++*u.m_pnUse;

//注意这里,改变了const引用的内部的指针的内容
if( --*m_pnUse == 0 )
{
delete m_pnUse;
m_pnUse = u.m_pnUse;
return true;
}
m_pnUse = u.m_pnUse;
return false;
}
bool MakeOnly() // 强制句柄成为唯一一个
{
if( *m_pnUse == 1 )
return false;
--*m_pnUse;
m_pnUse = new int(1);
return true;
}
bool Only()//检查是否句柄是当前唯一一个
{
return *m_pnUse == 1;
}
private:
int *m_pnUse;
};
class Handle
{
public:
Handle(const char *Name):m_pShow(new Show(Name)){}
~Handle()
{
if(m_UseCount.Only())
{
delete m_pShow;
}
}
Handle& operator=(const Handle &h)
{
if( m_UseCount.reattach(h.m_UseCount) )//这里传递的也是const的引用
delete m_pShow;
m_pShow = h.m_pShow;
return *this;
}

private:
Show *m_pShow;
UseCount m_UseCount;

};
int main()
{
Handle handle1("handle1");
Handle handle2("handle2");
handle1 = handle2;
}
上面这段程序是C++沉思录中的,koenig的作品。不知大家有什么看法?
ScorpioZZR 2003-08-21
  • 打赏
  • 举报
回复
顺便说一句,楼主结贴时不用给我分啊,呵呵,这个id我9月就弃用了。
注册新的换个马甲哈哈
ScorpioZZR 2003-08-21
  • 打赏
  • 举报
回复
我的看法嘛……嘿嘿……不知道:PPPP
来帮你up的!
哎哟,眼睛又开始痛了~~~~
不好,我下了。
现在我每天上5次,每次10分钟。疼啊我的eyes....
jyfcsdn 2003-08-21
  • 打赏
  • 举报
回复
我觉得无法彻底解决这个问题,但可以减少出现这种情况机会

我觉得会出现你写的这个问题的一个重要的原因是把int *a;暴露在类的接口里了,使得客户代码可以轻易地写下++*t.a;这样的语句。如果把a申明为私有成员,并提供非const的成员函数接口来改变a所指向的内容,那样的话可以在一定程度上遏止出现这种错误的情况。当然,如果一个不清楚这种错误的人还是可能写下const的成员函数,但是错误地改变了a指向的内容,这是不可能完全避免的。

我回遵循不在接口中暴露成员变量的方法来遏止这种错误的出现。不知你有何想法?
pengzhenwanli 2003-08-20
  • 打赏
  • 举报
回复
我是向大家说说你们的看法。关于改变const引用所含指针指向内容值的改变,你们会怎样用?一回我就给帖子加分。
pengzhenwanli 2003-08-20
  • 打赏
  • 举报
回复
我是向大家说说你们的看法。关于改变const引用所含指针指向内容值的改变,你们会怎样用?一回我就给帖子加分。
danielhf 2003-08-20
  • 打赏
  • 举报
回复
是啊, 只要把 ++*t.a 改为 ++t.a 就会出现:
error C2166: l-value specifies const object

a的值不能被改变, *a可以,

当你把 int* a 改为 const int* a 的时候
在 ++*t.a 的情况下,同样提示又出现:
error C2166: l-value specifies const object
pengzhenwanli 2003-08-20
  • 打赏
  • 举报
回复
是的。我改变的是指针a所指向内容的值,没有改变指针a,所以const引用照样可以改变它的内部指针所指向内容的值。
但是直觉上,应该认为const的引用不应该改变着各类对象的所有的值。是不是这样?
如果大家使用const的引用,是不是应该认为也不改变类对象内容的中的指针所指向的内容的值?如果是你用const的引用,会不会改变它内部指针所指向的内容?
这个例子是我从《Ruminations On C++》中的一个用法,简化而来。
Koenig就使用了个const引用来改变它所指向的内容的
5956 2003-08-20
  • 打赏
  • 举报
回复
障眼法,呵呵
lifanxi 2003-08-20
  • 打赏
  • 举报
回复
你改的是Test的对象中a指针所指的内存空间,它不属于Test的对象的一部分,也就是说Test的对象本身并没有变,所以我觉得没什么奇怪的。
hyifeng 2003-08-20
  • 打赏
  • 举报
回复
被骗,一点都不奇怪,没有改变test.a,只是改变了*tast.a而已!
jyfcsdn 2003-08-20
  • 打赏
  • 举报
回复
没什么奇怪的,t是const的,所以你不可以改变t的成员变量的内容t.a的内容,也就是地址,但是决不会组织你改变t.a指向的变量的内容,应为那个变量是Test类之外的,不是Test的成员
加载更多回复(2)

64,282

社区成员

发帖
与我相关
我的任务
社区描述
C++ 语言相关问题讨论,技术干货分享,前沿动态等
c++ 技术论坛(原bbs)
社区管理员
  • C++ 语言社区
  • encoderlee
  • paschen
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
  1. 请不要发布与C++技术无关的贴子
  2. 请不要发布与技术无关的招聘、广告的帖子
  3. 请尽可能的描述清楚你的问题,如果涉及到代码请尽可能的格式化一下

试试用AI创作助手写篇文章吧