【C++學習教程08】函式
阿新 • • 發佈:2021-01-02
目錄
參考
- 範磊C++(第十課時)
- VS2015
筆記
普通函式的過載
普通函式可以過載
成員函式的過載
成員函式也可以被過載
函式的預設引數
- 函式引數的初始化操作。叫預設引數又叫預設(shen)引數。
- 若在呼叫時沒有傳遞值時,則會使用預設值。
- 成員函式也可以有預設值。
- 過載函式建議增加預設值?
過載建構函式
- 建構函式可以過載但是隻能執行一個
成員變數的初始化
- 建構函式體中進行初始化;
- 在建構函式的函式頭進行初始化;
成員變數的初始化與建構函式
- 構造成員和析構成員的順序(第二節課件損壞)
#include "stdafx.h" #include <stdlib.h> #include <iostream> using namespace std; class A { public: A(int a, int b) { num = a; total = b; }//但是常量和引用不能被賦值!! private: int num; int total; }; int main(int argc, const char * argv[]) { return 0; }
建構函式和NEW運算子
#include "stdafx.h" #include <stdlib.h> #include <iostream> using namespace std; class A { public: A() { cout << "建構函式執行完畢" << endl; } void set(int a, int b) { i = a; j = b; } void print() { cout << i << endl; cout << j << endl; } private: int i; char j; }; int main(int argc, const char * argv[]) { A *a = new A;//在堆中建立物件 a->set(3, 5);//指標要用成員指標運算子 //ascii碼5對應的字元 a->print(); system("pause"); return 0; }
再談預設的建構函式
- 當不定義建構函式時,C++將預設定義一個不帶引數的建構函式。
- 當你創造建構函式之後,編譯器就不會再提供預設建構函式。
- 不加訪問修飾符的會預設為私有的。
複製建構函式
- 複製建構函式可以複製一個物件
#include "stdafx.h"
#include <stdlib.h>
#include <iostream>
using namespace std;
class A
{
public:
A() { cout << "建構函式執行完畢" << endl; }
A(A& one) { this->n = one.n; m = one.m; }
//複製建構函式,引數為類A物件的一個引用,可以通過引數來接受A的引數,one就是一個別名
//每一個類都有,不定義編譯器會自動定義,實現成員的對拷貝
A(int i, int j) { n = i; m = j; }//帶引數的建構函式
void print()
{
cout << n << m;
}
private:
int n;
int m;
};
int main(int argc, const char * argv[]) {
A a(2, 4);
a.print();
cout << "\n" << endl;
A b(a);//傳遞物件會呼叫複製建構函式 //將成員進行拷貝
b.print();
system("pause");
return 0;
}
解構函式和delete運算子
- 解構函式和delete的搭配使用
- delete會自動呼叫解構函式來釋放new運算子所建立的記憶體空間。
預設解構函式
-不定義的話,編譯器會預設定義解構函式。
呼叫建構函式進行型別轉換
#include "stdafx.h"
#include <stdlib.h>
#include <iostream>
using namespace std;
class A
{
public:
explicit A(int x) { i = x; cout << "建構函式執行完畢" << i<<endl; }//關閉這種特性,來制止隱式轉化
~A(){ cout << "解構函式在執行" <<i<< endl; }
void get() { cout << i << endl; }
private:
int i;
};
int main(int argc, const char * argv[]) {
A a(99);
a.get();
//a = 1000;//隱式轉化
a = A(1000);//數值賦給物件 //型別轉換 //這是在呼叫建構函式 //相當於建立了臨時物件
//引數個數和建構函式的個數一樣
//但是這樣會導致一些意外,所以應該關閉這種特性,但是顯示轉換是可以的。
//呼叫建構函式建立臨時物件,將臨時物件的成員i賦值給a的成員i,建立了臨時物件,所以會呼叫解構函式。
a.get();
system("pause");
return 0;
}
輸出結果:
淺層複製建構函式
如果發生了delete操作,則會觸發程式崩潰。
#include "stdafx.h"
#include <stdlib.h>
#include <iostream>
using namespace std;
class A
{
public:
A() { x = new int; *x = 5; }
~A() { delete x; x = NULL; }//C++區分大小寫
A(const A&a) { cout << "複製建構函式執行" << endl;
x = a.x;
}
void print() { cout << *x << endl; }
void set(int i) { *x = i; }
private:
int *x;
};
int main(int argc, const char * argv[]) {
A *a = new A();
cout << "a:";
a->print();
A b = (*a);//將一個物件複製給另一個物件,這時候會呼叫複製建構函式
b.print();
a->set(32);//a和b的x指向同一塊記憶體
cout << "a:";
a->print();
cout << "b:";
b.print();
//delete a;//此時會報錯,
system("pause");
return 0;
}
輸出結果:
第二課時失效
深層複製建構函式
#include "stdafx.h"
#include <stdlib.h>
#include <iostream>
using namespace std;
class A
{
public:
A() { x = new int; *x = 5; }
~A() { delete x; x = NULL; }
//深層複製建構函式
A(const A&a)
{
cout << "複製建構函式執行" << endl;
x=new int;//用複製建構函式建立的新物件的指標成員x來指向它。//兩個物件的x指標指向不同的記憶體
*x = *(a.x);//不再複製指標而是複製指標的值
}
void print() const { cout << *x << endl; }
void set(int i) { *x = i; }
private:
int *x;
};
int main(int argc, const char * argv[]) {
A *a = new A();
cout << "a:";
a->print();
A b = (*a);//將一個物件複製給另一個物件,這時候會呼叫複製建構函式
b.print();
a->set(32);
cout << "a:";
a->print();
cout << "b:";
b.print();
delete a;
//a->print();
b.print();
system("pause");
return 0;
}
輸出結果: