Effective C++ (喉结译,华中版) p94 ,有关const...
原文如下:
class String{
public:
String(const char *value);
...
operator char * () const {return data;} //?????????
private:
char *data;
};
const String s="Hello";
char *nasty=s; //调用char*()const
*nasty='M';
cout<<s; //输出“Hello”
1.上面operator char * () const {return data;} “char”的位置不对吧,
否则operator返回形别是什么呢,另外这里的“const”起什么作用?
2.原文说char *nasty=s; //调用char*()const
这里怎么调用了char*()const呢?想不通。
3.原文说cout<<s; //输出“Hello”
这里我觉得肯定输出Hello啊,s又没做什么,不过我知道肯定没这么简单的,
肯定有什么玄机在里面的吧。
请教各位!
问题点数:50、回复次数:29Top
1 楼Wolf0403(废人:独活十年~心如刀割)回复于 2003-12-01 09:19:48 得分 5
operator 型别 (); 这样的成员函式声明,是声明了一个类型转换操作符
operator char * () 就是将 String 转换成 char * 的类型转换操作符。因为是操作符,所以用 operator 在前面。因为转换规定了返回类型,所以 operator 前面没有返回类型。
const 表示这个函式不会修改对象本身,因此可以在 const object 上 invokeTop
2 楼nirvana_li(东成西就,芝兰境界)回复于 2003-12-01 09:46:31 得分 0
前两个问题,就是Wolf0403(完美废人)讲的,第3个问题原因在这里:
const String s="Hello";
char *nasty=s; //调用char*()const
*nasty='M';
cout<<s; //当然输出“Hello”
String型别的s被转换为char* 型别,由一个nasty指针指向它,然后nasty指向一个新的字符'M',但是s的值并没有变.所以输出s 的时候当然应该是Hello了哦...呵呵..
Top
3 楼fireseed(【VC无敌,英明神武,千秋万代,一统江湖!】—奶油狗)回复于 2003-12-01 10:19:02 得分 5
1. C++认为任何类型关键字,也是一种强制转换运算符,它的默认语义是把对象强制转换成那种类型。
2. 同上
3. cout的<<是个模版,它的参数在被给赋予你的s的时候,编译器会去查找相关的匹配,cout当然不支持你的String,但是编译器发现你的String重载了char的转换操作符,而cout的<<也支持char,所以就按照char来处理了Top
4 楼fierygnu(va_list)回复于 2003-12-01 10:23:21 得分 0
最后一个的输出应该是Mello,不是Hello。Top
5 楼fierygnu(va_list)回复于 2003-12-01 10:25:12 得分 0
*nasty='M'是给s[0]赋值,不是“指向一个新的字符'M'”。Top
6 楼timepalette(时间调色板)回复于 2003-12-01 13:12:01 得分 0
楼主: 书上写的输出到底是"Mello"还是"Hello"
Top
7 楼transformers()回复于 2003-12-01 16:19:37 得分 2
同意 fierygnu(va_list):
只有这样第一才不会修改“Hello”:
operator const char*() const {return data;}Top
8 楼sunjx119(睿锐)回复于 2003-12-01 17:52:12 得分 0
原书是说输出“Hello”Top
9 楼fierygnu(va_list)回复于 2003-12-01 17:57:27 得分 0
怎么可能。。。查原版的看看。
Top
10 楼fierygnu(va_list)回复于 2003-12-01 17:59:38 得分 0
这应该是一个说明避免返回类成员变量的非const指针或引用的最好例子。Top
11 楼ctang()回复于 2003-12-01 18:24:02 得分 0
实际上是输出 "Mello"Top
12 楼sunjx119(睿锐)回复于 2003-12-01 21:43:48 得分 0
对了,还有一句
//constructor 使date指向“value所指对象”的一份副本Top
13 楼MatrixCpp(the one)回复于 2003-12-01 22:01:36 得分 0
1,转型操作定义
2,转型操作调用
3,无论是否//constructor 使date指向“value所指对象”的一份副本
char *nasty=s; //调用char*()const
*nasty='M';
都是实实在在的通过指针间接的修改了变量s
所以输出都应该是"Mello"
Top
14 楼sunjx119(睿锐)回复于 2003-12-01 22:11:07 得分 0
to:Wolf0403(完美废人),
nirvana_li(东成西就),
fireseed(奶油狗【一打开BCB,就象在蹲茅坑!】)
.....
char *nasty=s; //调用char*()const
这句话里面,nastry是怎么调用这个“char*()const”operator 的呢,
还是不很明白,operator 的调用不是一般是这样的吗?
比如:
定义一个成员operator:
MyInt operator +=(MyInt &rhs);
当你这样调用时:
MyInt a,b;
a+=b;
实际上是:a.operator +=(b);
如果是这样子的话,对于刚才那个问题,就会有这样的推论:
原书:char *nasty=s; //调用char*()const
那我可以这样理解了:
operator这样子被调用:nasty.char *(); ......???? s哪里去了,况且nasty也不是String类的呀,到底应该怎么理解呢?
多谢各位先~
Top
15 楼ambition2005(惑)回复于 2003-12-01 22:13:07 得分 0
呵呵
同意楼上的
operator char * () const {return data;}
这句好象是拥护定义类型转换Top
16 楼sunjx119(睿锐)回复于 2003-12-01 22:15:24 得分 0
to MatrixCpp(the one):
我觉得你的说法似乎有些不妥吧,
date指向的是“value所指对象”的一份副本,
那既然是副本,又怎么能够“实实在在”的通过指针修改原来的本体呢?
Top
17 楼MatrixCpp(the one)回复于 2003-12-01 23:28:14 得分 5
我的EFC++不在手头上,看不到你说的东西
但就理解是每个String对象的data所指向的字符传是副本关系
但是s.data和char *nasty总是指向同一个字符串吧?
那和对象之间是否是共享有什么关系?
Top
18 楼sunjx119(睿锐)回复于 2003-12-01 23:35:05 得分 0
to 楼上:
是的s.data和char *nasty总是指向同一个字符串的
我不太理解你最后一句话的意思
我的意思只是nasty的改动,影响了s.date,但是s的value本身并不受影响Top
19 楼glacierrr(冰河纪的怪鸟)回复于 2003-12-01 23:38:58 得分 5
#include <iostream>
using namespace std;
class String
{
public:
String(const char *value);
~String();
operator char * () const { return data; } //?????????
char *data; // 为了方便,将data成员public
private:
};
String::String(const char *value)
{
data = new char[strlen(value) + 1];
strcpy(data, value);
}
String::~String()
{
delete []data;
}
void main()
{
const String s = "Hello";
char *nasty = s; //调用char*()const
*nasty = 'M';
cout<< s << endl; //输出“0x00480050”
cout<< *s << endl; //输出“M”
cout<< s.data << endl; //输出“Mello”
}
我在vc6里面编译运行,得出以下过程:
运行完*nasty = 'M',这时*(s.data) = "Mello",
再执行cout << s,得到结果是0x00480050,这是s.data指向的字符串的地址。
再执行cout << *s,得到结果是M,这是s.data指向的字符串的首字符。
再执行cout << s.data,得到结果是Mello,这是s.data指向的字符串。
Top
20 楼sunnussunnus(...软件工程背景...)回复于 2003-12-02 00:04:11 得分 5
向楼上学习,不懂的先问vc6.0和msdn...Top
21 楼transformers()回复于 2003-12-02 09:27:07 得分 0
To 楼主:
...
...
“operator这样子被调用:nasty.char *(); ......???? s哪里去了,... ”
你这样理解是不对的!!
应该是:operator.(char *)nasty = s ;
Top
22 楼fierygnu(va_list)回复于 2003-12-02 09:42:16 得分 16
1、应该是Mello
2、 char *nasty = s,编译器要进行类型匹配,s自己是String,不匹配,所以检查s的类型转换操作符,找到了operator char*() const可以匹配,所以这句成为char *nasty = s.operator char*()。是作用于s的,不是nasty。
3、value和这里的讨论没有关系,只是构造函数的一个参数,是临时变量。“constructor 使date指向“value所指对象”的一份副本”的意思是说s的成员变量data是value所指对象的拷贝,也就是说是data = strdup(value)的关系,而不是data = value的关系。
现在清楚了吗?Top
23 楼liem(阿明)回复于 2003-12-02 11:10:14 得分 2
s是个const对象,但其成员不一定是const的。
对于const对象,我们不能对其作整体的修改,但对其非const成员是可以修改的(局部小手术)。因此
*p='M';后,s.data的值是"Mello"
cout<<s;将s转换成char *后输出。Top
24 楼glacierrr(冰河纪的怪鸟)回复于 2003-12-02 21:06:50 得分 0
我发了email给侯捷先生,等ing ....Top
25 楼sunjx119(睿锐)回复于 2003-12-03 13:30:00 得分 0
自己up...Top
26 楼fierygnu(va_list)回复于 2003-12-03 13:36:13 得分 0
为什么还up?Top
27 楼psbeond(LibUIDK界面库客服)回复于 2003-12-03 15:45:38 得分 5
是"Mello",
const String s="Hello";
char *nasty=s;
*nasty='M'; //其实在这里候捷就说修改s.data[0]了
cout<<s;Top
28 楼sunjx119(睿锐)回复于 2003-12-07 01:09:08 得分 0
to transformers() :
operator char * () const {return data;} 定义在类声明内
它是String的成员操作符
那么隐式的this指针被隐式地用做第一个参数
你的operator.(char *)nasty = s ;这是什么意思?Top
29 楼sunjx119(睿锐)回复于 2003-12-07 01:55:27 得分 0
明白了,结帖!Top




