c++ primer书中的一个疑问

eatsweetpotato 2009-03-17 10:07:58
14.9.2节中,“只能应用一个类类型转换”一小节中的一个例程如下:


class SmallInt
{
public:
SmallInt(int i = 0): val(i)
{
cout <<"SmallInt constructor"<<endl;
}
operator int() const
{
return val;
}
SmallInt(const SmallInt &)
{
cout <<"SmallInt copy constructor"<<endl;
}
private:
std::size_t val;
};

class Integral
{
public:
Integral(int i = 0): val(i)
{
cout <<"Integral constructor"<<endl;
}
operator SmallInt() const
{
return val % 256;
}
Integral(const Integral &)
{
cout <<"Integral copy constructor"<<endl;
}

private:
std::size_t val;
};

int calc(int);
Integral intVal;
SmallInt si(intVal); // ok: convert intVal to SmallInt and copy to si
int i = calc(si); // ok: convert si to int and call calc
int j = calc(intVal); // error: no conversion to int from Integral

创建 si 时使用 SmallInt 复制构造函数。首先调用 Integral 转换操作符产生一个 SmallInt 类型的临时值,将 int_val 对象转换为 SmallInt。然后(合成的)复制构造函数使用该对象值初始化 si。



对于SmallInt si(intVal)这一行我有些疑惑,按道理只有在复制初始化的时候才回调用复制构造函数,但这里却说“创建 si 时使用 SmallInt 复制构造函数”
要说调用复制构造函数,也只是在将Integral转为SmallInt时会调用,但结果却没有。
不知这是为何,望高手给说说
...全文
262 17 打赏 收藏 转发到动态 举报
写回复
用AI写文章
17 条回复
切换为时间正序
请发表友善的回复…
发表回复
  • 打赏
  • 举报
回复
楼主自己可以单独编译
Integral intVal;
cout << " :" <<endl;
SmallInt si(intVal);
这3句,可以很直观地看到过程。
  • 打赏
  • 举报
回复
SmallInt si(intVal);

这个过程有点麻烦。
intVal之前是自己的默认构造函数。
然后生成一个临时的SmallInt类,来接收intVal的转换,最后才是si调用复制构造函数。
wushichao1987 2009-03-18
  • 打赏
  • 举报
回复
留名,下午再看
ysysbaobei 2009-03-18
  • 打赏
  • 举报
回复
eatsweetpotato 2009-03-18
  • 打赏
  • 举报
回复
仍有一些不解
用codeblock编译,结果为:
Integral constructor
SmallInt constructor

用VC6 , 则为:
Integral constructor
SmallInt constructor
SmallInt copy constructor
SmallInt copy constructor
pengzhixi 2009-03-17
  • 打赏
  • 举报
回复
你想想,SmallInt si(intVal);intVal最后变成了SmallInt类型,那么就肯定是调用SmallInt的拷贝构造函数咯
eatsweetpotato 2009-03-17
  • 打赏
  • 举报
回复
[Quote=引用 10 楼 pengzhixi 的回复:]
只能应用一个类类型转换
看懂这句话,这句话就表示不能从IntVal转换成SmallInt类型然后再从SmallInt转换到int型,然后再调用SmallInt的那个构造函数
[/Quote]

谢谢你的好意提醒。
不过我问的不是这个
pengzhixi 2009-03-17
  • 打赏
  • 举报
回复
只能应用一个类类型转换
看懂这句话,这句话就表示不能从IntVal转换成SmallInt类型然后再从SmallInt转换到int型,然后再调用SmallInt的那个构造函数
eatsweetpotato 2009-03-17
  • 打赏
  • 举报
回复
了解,
忽略了一句话,
“对于类类型对象,只有指定单个实参或显式创建一个临时对象用于复制时,才使用复制初始化。”
eatsweetpotato 2009-03-17
  • 打赏
  • 举报
回复
[Quote=引用 3 楼 pengzhixi 的回复:]
你这里是 先将IntVal转换成SmallInt类型,然后再调用SmallInt的复制构造函数构造si
[/Quote]

按这样说的话,因为我加入了
SmallInt(const SmallInt &)
{
cout <<"SmallInt copy constructor"<<endl;
}
函数,那么调用复制构造的话,应该会输出SmallInt copy constructor的呀
但事实却没有
eatsweetpotato 2009-03-17
  • 打赏
  • 举报
回复
[Quote=引用 3 楼 pengzhixi 的回复:]
你这里是 先将IntVal转换成SmallInt类型,然后再调用SmallInt的复制构造函数构造si
[/Quote]

按这样说的话,因为我加入了
SmallInt(const SmallInt &)
{
cout <<"SmallInt copy constructor"<<endl;
}
函数,那么调用复制构造的话,应该会输出SmallInt copy constructor的呀
但事实却没有
ztenv 版主 2009-03-17
  • 打赏
  • 举报
回复
共同进步!
lzy340623339 2009-03-17
  • 打赏
  • 举报
回复
[Quote=引用楼主 eatsweetpotato 的帖子:]
14.9.2节中,“只能应用一个类类型转换”一小节中的一个例程如下:


C/C++ code
class SmallInt
{
public:
SmallInt(int i = 0): val(i)
{
cout <<"SmallInt constructor"<<endl;
}
operator int() const
{
return val;
}
SmallInt(const SmallInt &)
{
cout <<"SmallInt copy constructor"<<endl;
}
private:
std::size_t val;
};
[/Quote]
你的用法:
Integral intVal;
SmallInt si(intVal);
就正是使用了拷贝构造函数SmallInt(const SmallInt &)
ztenv 版主 2009-03-17
  • 打赏
  • 举报
回复
楼主还是先了解一下复制初始化和拷贝初始化吧,C++Primer里有介绍的;
pengzhixi 2009-03-17
  • 打赏
  • 举报
回复
你这里是 先将IntVal转换成SmallInt类型,然后再调用SmallInt的复制构造函数构造si
eatsweetpotato 2009-03-17
  • 打赏
  • 举报
回复
[Quote=引用 1 楼 xuexicplusplus 的回复:]
SmallInt si(intVal);就是你所说的复制初始化呀
[/Quote]


书上如是说:
当用于类类型对象时,初始化的复制形式和直接形式有所不同:直接初始化直接调用与实参匹配的构造函数,复制初始化总是调用复制构造函数。复制初始化首先使用指定构造函数创建一个临时对象(第 7.3.2 节),然后用复制构造函数将那个临时对象复制到正在创建的对象
直接初始化就是紧跟括号,例如int i(9);
复制初始化就是用'=',例如 T b = a;

于是,SmallInt si(intVal);则是直接初始化
xuexicplusplus 2009-03-17
  • 打赏
  • 举报
回复
SmallInt si(intVal);就是你所说的复制初始化呀

65,211

社区成员

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

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