Chinaunix首页 | 论坛 | 博客
  • 博客访问: 22475
  • 博文数量: 12
  • 博客积分: 616
  • 博客等级: 上士
  • 技术积分: 130
  • 用 户 组: 普通用户
  • 注册时间: 2009-07-09 10:25
文章分类

全部博文(12)

文章存档

2010年(12)

我的朋友
最近访客

分类: C/C++

2010-03-29 13:01:02

拷贝构造函数和赋值函数的区别

一个类会默认生成它的

string()  //默认普通构造函数

void string( const string &a ) //默认拷贝构造函数,如果自己不实现,会用这个默认的

                               //采用“位拷贝”的方式,对有成员指针的情况,一定有

                               //问 题, 因为“位拷贝”, 指向同一地址空间,自己

                               //实现,改成“值拷贝”

~stirng()  //默认析构函数

const string& operation=( const string &a ) //默认赋值函数,如果自己不实现,

                         //默认的也是采用“位拷贝”的方式

“位拷贝”, string a(b);

除了a,b对象的地址不一样, 但a,b成员对象都指向的同一地址空间。 如果delete a, 就会删掉b的内容,所以位拷贝,对有指针成员变量的类,非常危险

拷贝构造函数发生的例子:   
  A   a(1);     //调用构造函数,   
  A   b(a);    //调用拷贝构造函数   
  A   c=a;     //第一次赋值,因为对象还没初始化,还是调用拷贝构造函数,   
  c=b;         //已经初始化的对象才能调用赋值函数   
  void   f(A   a);     //函数声明   
  f(c);        //实参传递时调用拷贝构造函数,但是编译器会根据具体情况把这个过程优化掉

1.拷贝构造函数只有在定义一个新的类对象并且用已有的对象进行初始化时调用.

2.赋值函数只有在已经初始化(对象已定义)的情况下被调用

c++中的explicit关键字

c++中的explicit关键字用来修饰类的构造函数,表明该构造函数是显式的,既然有"显式"那么必然就有"隐式",那么什么是显示而什么又是隐式的呢?

如果c++类的构造函数有一个参数,那么在编译的时候就会有一个缺省的转换操作:将该构造函数对应数据类型的数据转换为该类对象,如下面所示:   class MyClass
{
public:
MyClass( int num );
}
....
MyClass obj = 10; //ok,convert int to MyClass   在上面的代码中编译器自动将整型转换为MyClass类对象,实际上等同于下面的操作:   MyClass temp(10);
MyClass obj = temp;   上面的所有的操作即是所谓的"隐式转换"。

如果要避免这种自动转换的功能,我们该怎么做呢?嘿嘿这就是关键字explicit的作用了,将类的构造函数声明为"显示",也就是在声明构造函数的时候前面添加上explicit即可,这样就可以防止这种自动的转换操作,如果我们修改上面的MyClass类的构造函数为显示的,那么下面的代码就不能够编译通过了,如下所示:   class MyClass
{
public:
explicit MyClass( int num );
}
....
MyClass obj = 10; //err,can't non-explict convert 


阅读(356) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~