posts - 134,comments - 22,trackbacks - 0
一 default memberwise initialization
   通常我们都会为非抽象类定义拷贝构造函数,如果没有定义时,我们以class的一个object作为另一个object的初值时,编译器内部以default memberwise initialization 方式完成,对于member class object 则不会拷贝,而是递归调用 memberwise initialization。
   copy constructor和default constructor一样,在必要的时候才由编译器产生出来。copy constructor 以初始化的方式复制object,另一种是指定值(assignment),通过copy assignment operator

二 bitwise copy semantics
   编译器是否合成出考构是看class是否展现了 bitwise copy semantics,

// declaration exhibits bitwise copy semantics
class Word {
public:
   Word( const char* );
   ~Word() { delete [] str; }
   // ...
private:
   int cnt;
   char *str;
};

如书中所说,这个展现了bitwise copy semantics,why?

// declaration does not exhibits bitwise copy semantics
class Word {
public:
   Word( const String& );
   ~Word();
   // ...
private:
   int cnt;
   String str;
};

这个没有展现,同样不明白。。。。。。。
对于后者,编译器就会合成出一个 copy constructor。

那么什么时候不展现bitwise copy semantics呢,分为四种情况
(1)class 内含一个member object ,后者声明有一个copy constructor,无论是程序员声明的,还是被编译器合成的。
(2)class 继承自的基类有一个copy constructor,无论程序员声明的,还是被编译器合成的。
   对于这2种情况,编译器必须将memb或base class的copy constru调用操作安插到被合成的copy constr中。
(3)class声明了一个或多个 virtual function时
(4)class派生的基类串中至少有一个virtual base class时。

   情况3中,类中会额外增加vptr和vbtl,故就不在展现bitwise seamantics了,编译器需要合成出一个copy constructor,以将vptr适当初始化。
   同类型的对象vptr指向的相同的vtbl,基类和派生类的不同,看一段程序

class b{
public:
    int i;
    virtual void f(){}
};
class d:public b{
public:
    int ii;
};

int main(void) {
    b bbb;
    d dob;
    d bob;
    cout<<&bbb<<" "<<&bbb.i<<" "<<endl;
    cout<<&dob<<" "<<&dob.i<<" "<<&dob.ii<<endl;
    cout<<&bob<<" "<<&bob.i<<" "<<&bob.ii<<endl;
    int *p=(int *)&bbb;
    int *p2=(int *)&dob;
    int *p3=(int *)&bob;
    cout<<"bbb vptr ->"<<*p<<endl;
    cout<<"dob vptr ->"<<*p2<<endl;
    cout<<"bob vptr ->"<<*p3<<endl;

    b bb2=dob;
    cout<<&bb2<<" "<<&bb2.i<<" "<<endl;
    int *p4=(int *)&bb2;
    cout<<"bb2 vptr ->"<<*p4<<endl;
    puts("end in main");
    return EXIT_SUCCESS;
}

输出:

0x22ff78 0x22ff7c
0x22ff68 0x22ff6c 0x22ff70
0x22ff58 0x22ff5c 0x22ff60
bbb vptr ->4409528
dob vptr ->4409544
bob vptr ->4409544
12 12
0x22ff48 0x22ff4c
bb2 vptr ->4409528
end in main

b bb2=dob; 语句处,发生了派生类对象的切割,其vptr指向了基类的vbtl,而不是派生类。

参考文章:
转-复制概念相关,深拷贝与浅拷贝
posted on 2009-12-10 15:35 何克勤 阅读(206) 评论(0)  编辑  收藏 所属分类: C/C++

只有注册用户登录后才能发表评论。


网站导航: