首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 开发语言 > C++ >

瞅代码,关于拷贝构造函数

2012-07-30 
看代码,关于拷贝构造函数C/C++ code#include IOSTREAMusing namespace stdclass A{public:explicit A(c

看代码,关于拷贝构造函数

C/C++ code
#include <IOSTREAM>using namespace std;class A{public:    explicit A(const char c)    {        cout<<"构造函数"<<endl;    }    A(const A& a)    {        cout<<"拷贝构造函数"<<endl;    }};int main(){    char c = 0;    A a = c; //这里编译错误:cannot convert from 'char' to 'class A',        //A a(c);正常,为什么?    return 0;}


去掉构造函数中的explicit能编译通过。但是这个错误我就不明白了,怎么会有'char' to 'class A'的转换发生?
A a = c;中,到底是调用构造函数,还是拷贝构造函数呢?


[解决办法]
你这里会先调用构造函数,但是这个构造函数你没写,不存在,无参数的构造函数。所以会出错。然后调用的赋值操作 operator=
[解决办法]
探讨
引用:

你这里会先调用构造函数,但是这个构造函数你没写,不存在,无参数的构造函数。所以会出错。然后调用的赋值操作 operator=


不是这样的,即使加上默认构造函数,仍然报同样错误

[解决办法]
没重载operator=

[解决办法]
如果没有explicit 那么A a = c;就相当于 A temp(c); A a=temp;再配合优化的话 可以直接是A a(c);
[解决办法]
楼上说的不太对哦。
1.explicit 这个是用来指定构造函数不用来进行隐式类型转换的
2. A a = XXX这么写是会调用拷贝构造函数的。
所以正确的理解是,当你不写explicit时,编译器判断 A a = c;这句,A的拷贝构造函数是需要一个A的对象的引用的,所以进行了隐式类型转换,把c给了A的构造函数,构造出了一个临时的A对象,并将这个对象以引用的方式传入了拷贝构造函数。最后成功构造出了a。
如果你写了explicit,隐式类型转换不会被触发。所以就报错了cannot convert from 'char' to 'class A',因为你等号右边确实是个char类型的东西。
[解决办法]
探讨
C/C++ code

#include <IOSTREAM>
using namespace std;

class A
{
public:
explicit A(const char c)
{
cout<<"构造函数"<<endl;
}

A(const A&amp; a)
{
cout<<"……

[解决办法]
而且operator=需要是两个已经构造好的对象之间的赋值
[解决办法]
这个问题不好回答。按照道理来说是先用c产生了一个临时对象,然后调用了拷贝构造函数。但是,这样的代码被编译器给你优化了,直接调用了构造函数,没有其它的步奏了。用VS也验证了只有一个构造函数被调用。
[解决办法]
大家回帖好快,我说不对的是 1楼
[解决办法]
A(const char c)叫转换构造函数,它实际上担负的是从源类型到A类的转换角色。

对于A a = c,抽象语义上会先调用转换构造函数产生一个临时对象,然后用该临时对象通过复制构造函数初始化a,但是,编译器也可能会优化为在a中直接构造c,这时候复制构造过程被省略。
[解决办法]
A a=c,这个是直接给为一个class赋值,当然不对了
[解决办法]
改成A a; a = c;就好了。
[解决办法]
有explicit就阻止了 char 到A的一个转化
[解决办法]
这个是C++中隐身类型转换以及默认赋值函数的问题。

1、使用explicit可以防止出现隐式类型转换,所以会出现LZ那样的报错。
2、当不使用explicit的时候,如果使用单个参数的构造函数创建对象,但是自己在类中未定义单个参数的构造函数,则C++使用隐式类型转换。
3、当未重载赋值操作符=,自己却使用的时候,C++使用默认赋值函数。

所以
C/C++ code
A a = c; //这里编译错误:cannot convert from 'char' to 'class A',        //A a(c);正常,为什么?
[解决办法]
探讨

引用:

A(const char c)叫转换构造函数,它实际上担负的是从源类型到A类的转换角色。

对于A a = c,抽象语义上会先调用转换构造函数产生一个临时对象,然后用该临时对象通过复制构造函数初始化a,但是,编译器也可能会优化为在a中直接构造c,这时候复制构造过程被省略。




不太理解,抽象语义上会先调用转换构造函数产生一个临时对象,然后用该临时对象通……


[解决办法]
没有explicit 那么A a = c;就相当于 A temp(c); A a=temp;再配合优化的话 可以直接是A a(c);
有explicit那么 A temp(c)这个就被阻止了。也就不会有A a=temp这步骤了。
[解决办法]
A a = c;这种形式编译器使用构造函数A a()把c变成一个临时的A的变量,然后使用复制构造函数从新创建一个临时的对象并对其进行初始化,这样的做法付出的代价是两个构造函数以及一次析构函数,而直接使用A a(c);只付出一个构造函数的代价,所以前面那种做法完全是在浪费资源。
[解决办法]
不过有些编译器会做优化,优化之后效果一样。不做优化建议使用后面那种。
[解决办法]
A a = c 就是 A a(c)。绝对不会跟operator = 扯上关系,以前没有,现在没有,将来也不会有。

这个叫隐式调用构造函数,就是虽然看起来是个=,但其实就是调用的构造函数,所以叫隐式。
explicit英文的意思就是显示,你在构造函数前加一个这个东西就是告诉编译器禁止隐式调用构造函数。编译器当然报错了。

[解决办法]
探讨

A a = c 就是 A a(c)。绝对不会跟operator = 扯上关系,以前没有,现在没有,将来也不会有。

这个叫隐式调用构造函数,就是虽然看起来是个=,但其实就是调用的构造函数,所以叫隐式。
explicit英文的意思就是显示,你在构造函数前加一个这个东西就是告诉编译器禁止隐式调用构造函数。编译器当然报错了。

[解决办法]
好多人说的差不多都对了,LZ看看《inside the c++ object model》 或者《effective C++》《more effec C++》吧!
[解决办法]
#include <iostream>
using namespace std;
class A
{
private:

char i;

public:
A(const char c)
{
cout<<"构造函数"<<endl;
}
A()
{
}


~A()
{
cout<<"析构函数"<<endl;
}

 



};
 f(A a)
{
cout<<"拷贝构造函数"<<endl;
}
int main()
{
/*char c = 0;

A a = c; //这里编译错误:cannot convert from 'char' to 'class A',
//A a(c);正常,为什么?*/

char c=0;


A a(c);
A b=f(a);


return 0;
}

[解决办法]
#include <iostream>
using namespace std;
class A
{
private:

char i;

public:
A(const char c)
{
cout<<"构造函数"<<endl;
}
A()
{
}


~A()
{
cout<<"析构函数"<<endl;
}

 



};
 f(A a)
{
cout<<"拷贝构造函数"<<endl;
}
int main()
{
/*char c = 0;

A a = c; //这里编译错误:cannot convert from 'char' to 'class A',
//A a(c);正常,为什么?*/

char c=0;


A a(c);
A b=f(a);


return 0;
}

[解决办法]
explicit就是防止 A a = c; 这种赋值发生的。
A a(c);正常,为什么?==>因为这是调用了拷贝构造函数。
[解决办法]
因为explicit抑制由构造函数定义的隐式转换,来防止在需要隐式转换的上下文中使用构造函数。

因此当你定义 char c 来为 A a赋值时,explicit阻止了将 char c转换为class A类型,因此就出错了

如果楼主想要赋值,可以显示的使用构造函数
例如:
A a = A(c);
这样就行了。

热点排行