class TestChild
{
public:
TestChild()
{
x=0;
y=0;
printf("TestChild: Constructor be called!\n");
}
~TestChild(){}
TestChild(const TestChild& tc)
{
x=tc.x;
y=tc.y;
printf("TestChild: Copy Constructor called!//因為寫在了Test(拷貝)構(gòu)造函數(shù)的初始化列表里\n");
}
const TestChild& operator=(const TestChild& right)
{
x=right.x;
y=right.y;
printf("TestChild: Operator = be called! //因為寫在了Test(拷貝)構(gòu)造函數(shù)的函數(shù)體里\n");
return *this;
}
int x,y;
};
class Test
{
public:
Test(){printf("Test: Constructor be called!\n");}
explicit Test(const TestChild& tcc)
{
tc=tcc;
}
~Test(){}
Test(const Test& test):tc(test.tc)
{
tc=test.tc;
printf("Test: Copy Constructor be called!\n");
}
const Test & operator=(const Test& right)
{
tc=right.tc;
printf("Test: Operator= be called!\n");
return *this;
}
TestChild tc;
};
int main()
{
printf("1、Test中包含一個TestChild,這兩個類分別具有構(gòu)造函數(shù)、\n 拷貝構(gòu)造函數(shù)、重載operator=。\n\n");
printf("2、在調(diào)用Test的構(gòu)造函數(shù)和拷貝構(gòu)造函數(shù)之前,會根據(jù)跟在\n 這些函數(shù)后的初始化列表去初始化其\n TestChild變量(調(diào)用TestChild的拷貝構(gòu)造函數(shù)去初始化)\n\n");
printf("3、一旦進入Test的構(gòu)造函數(shù)體或拷貝構(gòu)造函數(shù)體,則說明其成員變量TestChild已\n 經(jīng)通過TestChild的構(gòu)造函數(shù)或TestChild的拷貝構(gòu)造函數(shù)構(gòu)造出了對象\n");
printf(" 所以,在Test的構(gòu)造函數(shù)體或拷貝構(gòu)造函數(shù)體中,再去使用=號\n 給TestChild的時候,調(diào)用的就是TestChild的operator=,\n 而不是TestChild的拷貝構(gòu)造函數(shù)了\n");
printf(" 這就是Test構(gòu)造函數(shù)后面 “:” 初始化列表的存在意義?。╘n 為了調(diào)用成員變量的構(gòu)造函數(shù)或者拷貝構(gòu)造函數(shù))\n\n");
printf("4、最后!揪出讓人困惑的終極原因!?。。。n Test test2=test1和Test test2(test1)這兩種是TM一模一樣的\n (都調(diào)用拷貝構(gòu)造函數(shù))?。。。〕诉@點兒之外,其他地方都是該是什么是什么(\"()\"調(diào)用構(gòu)造函數(shù),\"=\"調(diào)用賦值操作符)?。?!\n\n");
printf("5、一個對象初始化完畢后,所有對這個對象的賦值都調(diào)用operator=\n\n輸出如下:");
printf("Test test1; DO:\n");
Test test1;
printf("\n");
printf("Test test2=test1; DO:\n");
Test test2=test1;
printf("\n");
printf("Test test3(test2); DO:\n");
Test test3(test2);
printf("\n");
printf("test3=test1; DO:\n");
test3=test1;
return 0;
}
|