explicit???

yuanye2008 2004-09-10 01:46:06
#include <iostream>
using namespace std;
class one
{
public:
one()
{cout << "one constructor" << endl;}
};
class two
{
public:
two(const one&) //explicit two(const one&)
{
cout << "two constructor" << endl;
}
};
void f(two)
{
}

int main()
{
one a;
f(a);//f(two(a))
system("pause");
return 0;
}

问题:
1、书上说上面这段代码的代价是隐藏了构造函数对two的调用
应该将two(const one&) ==〉explicit two(const one&)
f(a) ==〉f(two(a)),可是他们的输出都是:
one constructor
two constructor
我不太理解这段话的意思!!!
2、explicit是什么意思?为什么使用它后,只能将f(a) ==〉f(two(a))
...全文
141 18 打赏 收藏 转发到动态 举报
写回复
用AI写文章
18 条回复
切换为时间正序
请发表友善的回复…
发表回复
yuanye2008 2004-09-10
  • 打赏
  • 举报
回复
谢谢!您说得非常清楚。我明白一些了!
剩下的就让我自己慢慢理解,消化吧!
您已经回答我好几个问题了!
我现在结贴了!万分感谢!
我现在分不富裕(问题太多)
等我达到小康一定多给您分!
再次感谢!
248406869 2004-09-10
  • 打赏
  • 举报
回复
看来有很多的人都看过《thinking in c++》
freshairfly 2004-09-10
  • 打赏
  • 举报
回复
老兄,明白了没有,快受不了了 :)
freshairfly 2004-09-10
  • 打赏
  • 举报
回复
看来你是理解错了。

对于这个
four Four(1);
g(Four);
因为g函数的原型是g(three);,所以必须有东西(函数或者操作符)能把传入的four对象转换为three对象。
方法1:前面说了,构造函数可以进行隐式转换:
所以你可以定义一个three的带有four对象的构造函数,like this:
three(four &);
如果你定义了这个,
g(Four);
--------------------------就等于-----------------
three tempThree(Four); //或者 three tempThree = three(four &Four);
g(tempThree);
所以通过定义一个参数为four&的构造函数能够保证g(Four);顺利执行

方法2:通过在four里定义一个转换函数,就是:
operator three() const {return three(x);}
如果你定义了这个转换函数
g(Four);
--------------------------就等于-----------------
three tempThree = Four.three();
g(tempThree);
所以通过定义转换函数也能够保证g(Four);顺利执行


但是要注意一点,方法1和方法二,好像不能同时使用,我在编译器上试了,是有编译错误的




yuanye2008 2004-09-10
  • 打赏
  • 举报
回复
您看我理解的对不对?

three tempThree = three(four &Four)
而four &Four正好是重载操作符three隐藏的左值(参数),
所以调用g.three()对吗?
freshairfly 2004-09-10
  • 打赏
  • 举报
回复
three tempThree = tempThree(1);
-------------------------------------------------------
对不起,这个我打错了,应该是three tempThree = three(1);
这里之所以可以这样是因为three提供了一个
three(int I = 0, int =0)
这样的构造函数


那么g(Four)相当于
three tempThree = tempThree(Four);
g(tempThree);
------------------------------------------
你这里也打错了,我想你应该是这个意思吧:three tempThree = three(Four);
但three类没有提供一个这样的构造函数:
three(four &Four)

如果提供了,上面这构造函数,会引起编译器的识别困难,我试了一下,编译通不过
不过你把operator three() const {return three(x);}注释掉,就会执行
three tempThree = three(Four);
g(tempThree);
yuanye2008 2004-09-10
  • 打赏
  • 举报
回复
问题:
我试过了,确实调用Four.three(),按您第二各问题的解答
g(1) 相当于
three tempThree = tempThree(1);
g(tempThree);
那么g(Four)相当于
three tempThree = tempThree(Four);
g(tempThree);

我实在看不出来它为什么调用Four.three()。
操作符重载我学得不太明白!
freshairfly 2004-09-10
  • 打赏
  • 举报
回复
1、所以g(Four);会调用把它转换为three对象
怎样转换:是g(Four.three())这样吗?,如何看出她调用three()的
--------------------------------
对。你可以在operator three()打印一些信息看看

2、g(1);调用了three的构造函数进行转换(转换为three对象)
这不是符值吗?将1符值给three,怎么会是调用了three的构造函数
--------------------------------
不是赋值,是构造一个three
其实g(1)就相当于下面的代码:
three tempThree = tempThree(1);
g(tempThree);
yuanye2008 2004-09-10
  • 打赏
  • 举报
回复
问题:
1、所以g(Four);会调用把它转换为three对象
怎样转换:是g(Four.three())这样吗?,如何看出她调用three()的
2、g(1);调用了three的构造函数进行转换(转换为three对象)
这不是符值吗?将1符值给three,怎么会是调用了three的构造函数

有点晕!
freshairfly 2004-09-10
  • 打赏
  • 举报
回复
class four
{
int x;
public:
four(int X):x(X){};
operator three() const {return three(x);}
---------------------------------------------------
这里你定义了一个转换函数,所以g(Four);会调用把它转换为three对象
};

g(1);调用了three的构造函数进行转换(转换为three对象)
yuanye2008 2004-09-10
  • 打赏
  • 举报
回复
丁!
yuanye2008 2004-09-10
  • 打赏
  • 举报
回复
#include <iostream>
using namespace std;
class three
{
int i;
public:
three(int I = 0, int =0):i(I){}
};
class four
{
int x;
public:
four(int X):x(X){};
operator three() const {return three(x);}
};
void g(three){}

int main()
{
four Four(1);
g(Four);
g(1); //calls three(1,0)
system("pause");
return 0;
}
各位说的我刚有点明白,但当我接着看下去,又发现其他相关问题
问题:
1、为什么函数g()需要的参数是对象three并且没有可以将fout隐式
转换为three的函数,为什么g(Four)不报错!
2、书上说这是通过操作副重载进行自动类型转换,如何理解
3、g(1);调用的是什么?
freshairfly 2004-09-10
  • 打赏
  • 举报
回复
刚开始俺也看成了拷贝构造函数~~,呵呵
积木 2004-09-10
  • 打赏
  • 举报
回复
今天还是头昏~,ft
freshairfly 2004-09-10
  • 打赏
  • 举报
回复
to goodboy1881(三井)(为了更好的BS JAVA而学习JAVA中)
-------------------------------
楼主定义的是构造函数(呵呵,不是拷贝构造函数)
freshairfly 2004-09-10
  • 打赏
  • 举报
回复
也就是说如果你把
two(const one&)申明为explicit

int main()
{
one a;
f(a);//f(two(a)) //这句话将编译通不过,因为你已经禁止了编译器的隐式转换
system("pause");
return 0;
}
积木 2004-09-10
  • 打赏
  • 举报
回复
explicit就是显式提供构造函数,防止进行隐式转换,隐式构造的意思。
你把拷贝构造函数进行这种explicit并没有作用啊,起作用的应该是
在构造函数前面提供explicit,而不是拷贝构造函数,
因为你的这个函数没有构造函数,所以编译器自己合成了一个,因为这个合成的前面没有explicit,因此各种隐式转换均成为可能~
freshairfly 2004-09-10
  • 打赏
  • 举报
回复
explicit的作用是禁止编译器的隐式转换

比如:
one o;
two t = o;//这里会调用two(const one&)方法,如果把two(const one&)申明为explicit,会有编译错误

64,654

社区成员

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

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