C++中的幾種特殊成員函數(shù)
構(gòu)造函數(shù)
C++在編譯器會給我們默認創(chuàng)建一個缺省的構(gòu)造方法: 如下代碼:
class Father {
public:
string name = "father";
int age = 45;
void print() {
cout << "name:" << name << " age:" << age << endl;
}
};
class Son :public Father {
public:
string sex = "male";
};
void extendsTest::mainTest()
{
Son son;
son.print();
};
運行結(jié)果:name:father age:45
可以看到雖然我們沒有明確聲明構(gòu)造方法,但是依然可以調(diào)用無參構(gòu)造方法。這就是因為 編譯器自動給我們創(chuàng)建了一個無參構(gòu)造方法 、
如果類定義了自己的構(gòu)造方法后(包括無參和有殘),編譯器就不會給我們創(chuàng)建了 ,看下面代碼:
class Father {
public:
Father() {
cout << "Father:" << name << endl;
}
string name = "father";
int age = 45;
void print() {
cout << "name:" << name << " age:" << age << endl;
}
};
class Son :public Father {
public:
Son(){
cout << "Son:" << name << endl;
}
string sex = "male";
};
void extendsTest::mainTest()
{
Son son;
son.print();
};
打印結(jié)果:
Father:father
Son:father
name:father age:45
從上面代碼也可以看出C++編譯器會默認優(yōu)先調(diào)用父類的構(gòu)造方法,再調(diào)用子類的構(gòu)造方法,
這點和java中是有區(qū)別的,java會從子類開始依次調(diào)用父類的構(gòu)造方法,然后回溯子類的構(gòu)造方法
所以為了保證對象的順利創(chuàng)建,需要保證父類的構(gòu)造方法是有效的。 如下代碼:
class Father {
public:
Father(string _name):name(_name){
cout << "Father:" << name << endl;
}
string name = "father";
int age = 45;
};
此時父類中創(chuàng)建了一個有參構(gòu)造方法,前面說過,此時編譯器不會創(chuàng)建默認的無參構(gòu)造方法,則需要保證在其子類中有初始化父類的操作:即調(diào)用父類有參構(gòu)造方法。 如下代碼:
class Son :public Father {
public:
Son(string name):Father(name) {
cout << "Son:" << name << endl;
}
string sex = "male";
};
void extendsTest::mainTest()
{
Son son1("myName");
};
結(jié)果:
Father:myName
Son:myName
析構(gòu)函數(shù)
析構(gòu)函數(shù)用來釋放當前對象使用到的內(nèi)存空間,當對象跳出其作用域范圍后就會執(zhí)行析構(gòu)函數(shù)( 除非是有智能指針出現(xiàn)循環(huán)引用的情況,無法釋放,導致泄露 )。 C++中析構(gòu)函數(shù)和構(gòu)造函數(shù)相反,會 優(yōu)先調(diào)用子類的析構(gòu)函數(shù)再調(diào)用父類的析構(gòu)函數(shù) 。 如下代碼:
class Father {
public:
~Father() {
cout << "~Father"<< endl;
}
string name = "father";
int age = 45;
};
class Son :public Father {
public:
~Son() {
cout << "~Son" << endl;
}
string sex = "male";
};
void extendsTest::mainTest()
{
Son son;
};
運行結(jié)果:
~Son
~Father
拷貝構(gòu)造
C++中拷貝構(gòu)造函數(shù)格式:
- 格式1 :帶const參數(shù) Complex(const Complex& c) { … } 表示以常量對象作為參數(shù)
- 格式2 :不帶const參數(shù) Complex(Complex& c) { … } 表示以非常量作為參數(shù)進行拷貝 如下代碼:
class Complex {
public:
double real, imag;
Complex(double _real, double _imag):
real(_real),imag(_imag)
{
cout << "real:" << real << " imag:" << imag << endl;
}
void print() {
cout << "real:" << real << " imag:" << imag << endl;
}
Complex(Complex& c) {
real = c.real+1; imag = c.imag+1;
}
};
void extendsTest::mainTest()
{
Complex c1(1.0, 2.0);
Complex c2(c1);
c2.print();
};
打印結(jié)果:
real:1 imag:2
real:2 imag:3
拷貝構(gòu)造函數(shù)和構(gòu)造方法類似, C++編譯器會給我們提供默認的拷貝構(gòu)造函數(shù) 。 將上面代碼的拷貝構(gòu)造函數(shù)刪除后:
class Complex {
public:
double real, imag;
Complex(double _real, double _imag):
real(_real),imag(_imag)
{
cout << "real:" << real << " imag:" << imag << endl;
}
void print() {
cout << "real:" << real << " imag:" << imag << endl;
}
};
void extendsTest::mainTest()
{
Complex c1(1.0, 2.0);
Complex c2(c1);
c2.print();
};
依然可以執(zhí)行拷貝構(gòu)造,此時c2使用了默認拷貝構(gòu)造函數(shù)進行賦值。
拷貝構(gòu)造的幾種調(diào)用形式:
-
1.當用一個對象去初始化同類的另一個對象時
Complex c2(c1); Complex c2 = c1;
這兩天語句是等價的。但是要 注意此時Complex c2 = c1是一個初始化語句,并非一個賦值語句。賦值語句是一個已經(jīng)初始化后的變量 。 如下:
Complex c1, c2; c1 = c2 ; c1=c2;
賦值語句不會觸發(fā)拷貝構(gòu)造 。
-
2.當對象作為一個函數(shù)形參時,此時也會觸發(fā)對象的拷貝構(gòu)造
class Complex { public: double real, imag; Complex(double _real, double _imag): real(_real),imag(_imag) { cout << "real:" << real << " imag:" << imag << endl; } Complex(Complex& c) { real = c.real+1; imag = c.imag+1; cout << "complex copy" << endl; } }; void func(Complex c) { cout << "real:" << c.real << " imag:" << c.imag << endl; } void extendsTest::mainTest() { Complex c(1.0,2.0); func(c); }; 運行結(jié)果: real:1 imag:2 complex copy real:2 imag:3
可以看到運行結(jié)果觸發(fā)了Complex的拷貝構(gòu)造 以對象作為函數(shù)的形參,在函數(shù)被調(diào)用時,生成的形參要用復制構(gòu)造函數(shù)初始化,這會帶來時間上的開銷。 如果用對象的引用而不是對象作為形參,就沒有這個問題了 。
void func(Complex& c) { cout << "real:" << c.real << " imag:" << c.imag << endl; }
但是以引用作為形參有一定的風險,因為這種情況下如果形參的值發(fā)生改變,實參的值也會跟著改變。 最好的方法就是將函數(shù)形參聲明為const類型的引用 。
void func(const Complex& c) { cout << "real:" << c.real << " imag:" << c.imag << endl; }
-
3.對象作為函數(shù)返回值返回時,也會觸發(fā)拷貝構(gòu)造。
Complex func() { Complex c(1.0, 2.0); return c; } void extendsTest::mainTest() { cout << func().real << endl; }; 結(jié)果: real:1 imag:2 complex copy 2
可以看到此時func函數(shù)中的return c處會觸發(fā)一次拷貝構(gòu)造,并將拷貝后的對象返回。 這點通過函數(shù)hack過程也可以看出來:此處call方法執(zhí)行的是拷貝構(gòu)造方法
-
JAVA
+關注
關注
20文章
2989瀏覽量
109814 -
C++
+關注
關注
22文章
2119瀏覽量
75330 -
面向?qū)ο缶幊?/span>
+關注
關注
0文章
22瀏覽量
1961
發(fā)布評論請先 登錄
C++面向對象多線程編程 (pdf電子版)
Visual C++面向對象與可視化程序設計習題解析與編程實

C#入門教程之面向對象編程簡介的詳細資料概述

嵌入式C語言面向對象編程應用及優(yōu)勢

評論