统计

  • 随笔 - 50
  • 文章 - 42
  • 评论 - 147
  • 引用 - 0

留言簿(6)

随笔分类

文章分类

Link

搜索

  •  

积分与排名

  • 积分 - 162616
  • 排名 - 161

最新评论

阅读排行榜

评论排行榜

再谈拷贝构造函数(Copy Constructor Function)

前段时间有人发表了关于拷贝构造函数的问题,我觉得对于拷贝构造函数要掌握四点(以下以CCF代称拷贝构造函数)
第一:默认CCF提供对象之间的位拷贝(Bitwise Copy),对于指针类成员只会将至指针值复制
第二:CCF在对象初始化时才发挥作用,而在对象赋值的时候不起作用
第三:在没有显示声明成员CCF的情况下,编译器会自动生成默认CCF,如果显示声明了显示CCF,则编译器不会生成默认CCF,至少是不会调用
第四:与构造函数不同,CCF并不会递归的调用基类的CCF,子类与基类的CCF是覆盖关系,与就是说子类会寻找与自己关系最近的CCF调用,如果子类有CCF则仅调用子类CCF,如果子类没有向上寻找,调用第一个找到的CCF
第五:CCF的声明及定义如下:

 1classname(classname const&obj)
 2{
 3   m1=obj.m1;
 4   m2=obj.m2;
 5   .
 6   Lp1=new type[size];
 7   memcpy_s(Lp1,size,obj.Lp1);
 8   Lp2=new type[size];
 9   memcpy_s(Lp2,size,obj.Lp2);
10   .
11}

而具体到第二点,CCF在以下情况下也会被调用:
  1) 一个对象以值传递的方式传入函数体;
  2) 一个对象以值传递的方式从函数返回;
  3) 一个对象需要通过另外一个对象进行初始化;
除此之外,对于对象复制是我们经常会忽略或混淆的一点,在对赋值的时候不会调用CCF,需要自己去重载“=”

注意:对于包含动态分配成员的类提供拷贝构造函数和重载"="赋值操作符号是一个良好的编程习惯。
愿意如下:
动态成员如指针,在默认CCF和默认“=”操作符下仅仅执行位拷贝,而指针所指向的内存区域不会被拷贝,造成内存错误操作
以下例程可用来实验:

#pragma once
#include 
"tchar.h"

class mycls
{
public:
    mycls(){};
    mycls(mycls const & obj)
 
{
        
//delete[] mp_str1;
        mp_str1=new TCHAR[100];
        _tcscpy_s(mp_str1,
100,obj.mp_str1);
    }

    
char a[100000];
    TCHAR b[
1000];
    
//~mycls(void);
    int m_q;
    TCHAR
* mp_str1;
    
char* mp_str2;
}
;
class mycls2:public mycls
{
public:
    mycls2():bb(
10){};
       mycls2(mycls2 
const&obj)
    
{
        bb
=obj.bb;
       }

       
int bb;
}
;


 

posted on 2008-12-05 23:19 pear_li 阅读(3906) 评论(12)  编辑 收藏 引用 所属分类: C++

评论

# re: 再谈拷贝构造函数(Copy Constructor Function) 2008-12-07 14:02 sheep

const& 是不是应该放在classname的前面啊~
  回复  更多评论    

# re: 再谈拷贝构造函数(Copy Constructor Function) 2008-12-08 00:59 pear_li

@sheep
??去补充一下基本知识吧,最多也只是将const提前,不过没有实质差别
  回复  更多评论    

# re: 再谈拷贝构造函数(Copy Constructor Function)[未登录] 2008-12-08 09:43 raof01

第一,是bitwise initialization,member-wise copy。——这话是Inside C++ Object Model里说的,我也认同这种观点。
第四,不会递归调用基类CCF,但会递归调用个成员的CCF。——越俎代庖,做个补充:)
  回复  更多评论    

# re: 再谈拷贝构造函数(Copy Constructor Function) 2008-12-08 17:00 sheep

恕我无知。
我还是认为拷贝构造函数的参数const放后有些问题。
如果放后面;如果这样调用
classname const a;
classname b(a);
在vc6.0和vs2005中编译时会出错,其他编译器没有试验
  回复  更多评论    

# re: 再谈拷贝构造函数(Copy Constructor Function) 2008-12-09 02:31 pear_li

@raof01
呵呵,多谢补充
  回复  更多评论    

# re: 再谈拷贝构造函数(Copy Constructor Function) 2008-12-09 02:50 pear_li

@sheep
你说的问题我没有遇到过,可以把出错信息贴出来吗?
  回复  更多评论    

# re: 再谈拷贝构造函数(Copy Constructor Function) 2008-12-09 10:32 sheep

vc6.0
Person(Person& const s) //出现警告
warning C4227: anachronism used : qualifiers on reference are ignored
Person p2(p1); //出现错误
error C2558: class 'Person' : no copy constructor available

vs2005
错误 4 error C2558: class“Person”: 没有可用的复制构造函数或复制构造函数声明为“explicit”

将const提到Person&的前面就不会又警告和错误,不知道怎么回事。
  回复  更多评论    

# re: 再谈拷贝构造函数(Copy Constructor Function) 2008-12-09 13:54 pear_li

@sheep
写成
Person(Person const& s)
就没问题了,关键在于const和&的顺序,与class无关
你那样写就相当于是引用常量,而引用无所谓常量变量,对于引用只有常量引用之说
  回复  更多评论    

# re: 再谈拷贝构造函数(Copy Constructor Function) 2008-12-10 00:37 sheep

多谢指点了~
  回复  更多评论    

# re: 再谈拷贝构造函数(Copy Constructor Function) 2008-12-10 20:59 pear_li

@sheep
呵呵,客气^_^
  回复  更多评论    

# re: 再谈拷贝构造函数(Copy Constructor Function) 2009-02-11 22:10 wingbake

写的很好,很受启发!
Mark!
  回复  更多评论    

# re: 再谈拷贝构造函数(Copy Constructor Function) 2009-05-22 16:28 thanks

thanks very much
  回复  更多评论    

只有注册用户登录后才能发表评论。
网站导航: 博客园   IT新闻   BlogJava   知识库   博问   管理