前言:
在c++类中,两个已存在的对象使用“=”赋值,这属于类的赋值,我们可以不用声明opreator =(),编译器会自动给类实现;
使用一个对象来新建一个新的对象的构造函数,称为 复制构造函数/拷贝构造函数。
- #include <iostream>
- #include <string>
- #include <vector>
- using namespace std;
- struct X
- { //simple test class
- int val;
- void out( const string& s,int nv )
- {
- cerr<<this<<"->"<<s<<":"<<val<<"( "<<nv<<")\n"; //注意,下面的构造函数都是先输出再给val赋值的,所以val是不确定的值
- }
- X( ) //default constructed function
- {
- out( "X( )" ,0);
- val=0;
- }
- X( int v )
- {
- out( "X( int )" ,v);
- val=v;
- }
- X( const X& x ) //a copy constructed funtion
- {
- out( "X( X& )",x.val );
- val=x.val;
- }
- X& operator =( const X& a ) //a evaluated function
- {
- out( "X::operator=( )",a.val);
- val=a.val;
- return *this;
- }
- ~X( ) //deconstructed function
- {
- out( "~X( )",0 );
- }
- };
- X glob( 2 ); //a global variable
- X copy( X a )
- {return a;}
- X copy2( X a )
- {X aa=a;return aa;}
- X& ref_to( X& a )
- {return a;}
- X* make( int i )
- {X a( i );return new X( a );}
- struct XX
- {
- X a;
- X b;
- };
- int main( )
- {
- X loc( 4 );
- X loc2=loc;
- loc=X( 5 );
- loc2=copy( loc );
- loc2=copy2( loc );
- X loc3( 6 );
- X& r=ref_to( loc );
- delete make( 7 );
- delete make( 8 );
- vector<X> v( 4 );
- XX loc4;
- X *p=new X( 9 );
- delete p;
- X* pp=new X[ 5 ];
- delete [ ] pp;
- return 0;
- }
结果如下:
winlin@winlin-Satellite:~/Mypro$ ./test
0x6031e0->X( int ):0( 2) // X glob(2); 这是全局变量glob,在main之前赋值,调用X( int ),全局变量初始值为0,val=0
0x7fff47f949e0->X( int ):1207520024( 4) // X loc(4); main中的第一个loc局部变量,调用X( int ),val是随即数1207520024
0x7fff47f949d0->X( X& ):0( 4) //X loc2=loc;main中第二个loc2局部变量,调用X( X& )复制构造函数,val是随机值
0x7fff47f949c0->X( int ):1( 5) //该句和下面2句,都是loc=X(5);一句的结果。首先X(5)先构造一个临时变量
0x7fff47f949e0->X::operator=( ):4( 5) //然后调用赋值构造函数,赋值给loc
0x7fff47f949c0->~X( ):5( 0) //然后析构生成的临时变量
/* X copy( X a )
{return a;}
*/
0x7fff47f949b0->X( X& ):1207519696( 5) //loc2=copy(loc); 由于是X copy(X a)使用的是值传递,所以先构造一个临时对象,传递给函数copy()
0x7fff47f949a0->X( X& ):1207519664( 5) //return a; 返回的也是一个构造出来的临时对象
0x7fff47f949d0->X::operator=( ):4( 5) //此时loc2.val=4;调用赋值构造函数
0x7fff47f949a0->~X( ):5( 0) //先析够return产生的临时对象
0x7fff47f949b0->~X( ):5( 0) //再析够作为参数的临时变量
/* X copy2( X a )
{X aa=a;return aa;}
*/
0x7fff47f94990->X( X& ):3077560( 5) //copy2(X a);原因同上,值传递要构造一个临时对像
0x7fff47f94980->X( X& ):6303212( 5) //这个是retrun aa;产生的临时对象,应该是由于编译器调整了顺序
0x7fff47f949d0->X::operator=( ):5( 5) //X aa=a
0x7fff47f94980->~X( ):5( 0) //同上原因
0x7fff47f94990->~X( ):5( 0)
0x7fff47f94970->X( int ):6303216( 6) // X loc3(6);
/* X& ref_to( X& a )
{return a;}
*/
// X& r=ref_to( loc ); 由于生成的r并没有在程序中继续使用,所以编译器进行优化,删除了语句
//编译的时候g++会给出提示:test.cpp:78: warning: unused variable ‘r’
/* X* make( int i )
{X a( i );return new X( a );}
*/ //delete make(7) ;
0x7fff47f948e0->X( int ):1207519616( 7) //X a(i);这一句构造的局部变量a
0x968080->X( X& ):0( 7) //new X(a) ; 调用的复制构造函数
0x7fff47f948e0->~X( ):7( 0) //析构a
0x968080->~X( ):7( 0) //析够new产生的对象
0x7fff47f948e0->X( int ):0( 8) delete make(8);
0x968080->X( X& ):0( 8)
0x7fff47f948e0->~X( ):8( 0)
0x968080->~X( ):8( 0)
//vector<X> v(4)
0x7fff47f94960->X( ):4200176( 0) //首先调用默认构造函数生成一个临时对象,用来对 vector v(4)进行初始化
0x968080->X( X& ):0( 0) //对v的四个成员进行初始化
0x968084->X( X& ):0( 0)
0x968088->X( X& ):0( 0)
0x96808c->X( X& ):0( 0)
0x7fff47f94960->~X( ):0( 0) //析构用来初始化的临时对象
/* struct XX
{
X a;
X b;
};
*/ // XX loc4;
0x7fff47f94950->X( ):6303928( 0) // 调用X的默认构造函数
0x7fff47f94954->X( ):2( 0)
//X *p=new X(9);
0x9680a0->X( int ):0( 9) //构造一个新的对象,X *p直接让p指向该对象即可
0x9680a0->~X( ):9( 0) //delete p;
// X *pp=new X[5];
0x968018->X( ):6( 0) //生成5个X对象,调用默认构造函数
0x96801c->X( ):0( 0)
0x968020->X( ):-1( 0) 0x968024->X( ):0( 0) 0x968028->X( ):539515006( 0)
0x968028->~X( ):0( 0) //delete pp;析构这5个变量。注意析构的顺序,先构造后析构
0x968024->~X( ):0( 0)
0x968020->~X( ):0( 0)
0x96801c->~X( ):0( 0)
0x968018->~X( ):0( 0)
0x7fff47f94954->~X( ):0( 0) //这时析构的是 XX loc4,中的两个X 对象
0x7fff47f94950->~X( ):0( 0)
0x968080->~X( ):0( 0) //这时析构vector<X> v(4)的四个X对象
0x968084->~X( ):0( 0)
0x968088->~X( ):0( 0)
0x96808c->~X( ):0( 0)
0x7fff47f94970->~X( ):6( 0) //析构loc3
0x7fff47f949d0->~X( ):5( 0) //析构loc2
0x7fff47f949e0->~X( ):5( 0) //析构loc1
0x6031e0->~X( ):2( 0) //析构全局变量glob
winlin@winlin-Satellite:~/Mypro$
后记:不知道结果中的地址数据有什么更深的含义?从这些简单的地址中我们能否得到什么令人兴奋的秘密那?
转载于:https://blog.51cto.com/liuguangtao/537723