C語言到C++ 物件和類的進一步學習2
阿新 • • 發佈:2018-11-15
1.淺拷貝
#define _CRT_SECURE_NO_WARNINGS #include <iostream> using namespace std; class Name { public: Name(const char *myp) { len = strlen(myp); p = (char*)malloc(len + 1); strcpy(p,myp); } ~Name() { if (p != NULL) { free(p); p = NULL; len = 0; } } protected: private: char *p; int len; }; void objplaymain() { Name obj0("zhan"); Name obj1 = obj0; //使用編譯器的預設的賦值建構函式 //只是簡單的將成員變數賦值 //free函式會重複釋放同一塊的記憶體 引起錯誤 //淺拷貝 //Name obj2("zhan"); //obj2 = obj1; //C++編譯器預設的 = 號也是淺拷貝 } int main06() { objplaymain(); //程式異常 system("pause"); return 0; }
2.深拷貝
#define _CRT_SECURE_NO_WARNINGS #include <iostream> using namespace std; class NameA { public: NameA(const char *myp) { len = strlen(myp); p = (char*)malloc(len + 1); strcpy(p, myp); } //淺拷貝的解決方案 手動編寫賦值建構函式 //深拷貝 NameA(const NameA &obj) { len = obj.len; p = (char*)malloc(len + 1); strcpy(p, obj.p); } ~NameA() { if (p != NULL) { free(p); p = NULL; len = 0; } } protected: private: char *p; int len; }; void objplaymain1() { NameA obj0("zhan"); NameA obj1 = obj0; } int main07() { objplaymain1(); //程式正常 system("pause"); return 0; }
3.建構函式的初始化列表
#include <iostream> using namespace std; //建構函式的初始化列表 解決:在B類中組合了一個A類的物件 //根據建構函式的呼叫規則 設計A的建構函式必須要用 //新的語法規則 Constructor::Constructor():m1(v1),m2(v2),m3(v3) class A { public: A(int _a) { a = _a; cout << "建構函式a:" << a << endl; } ~A() { cout << "解構函式a:" << a << endl; } protected: private: int a; }; class B { public: B(int _b):a1(4),a2(6) { b = _b; } protected: private: int b; A a1; //定義的順序 A a2; }; //1先執行 被組合物件的建構函式 //如果組合物件有多個 按照定義順序 而不是按照初始化列表的順序 //解構函式:和建構函式順序相反 //2被組合物件的構造順序和定義的順序有關係,與初始化列表的順序沒有關係 //在構造中呼叫建構函式 會產生一個新的匿名物件 int main08() { A a1(5); B b1(6); system("pause"); return 0; }
4.new和delete的基礎語法
#include <iostream>
using namespace std;
// malloc free C語言的函式
// new delete 操作符是C++的語法
//new可以分配 基礎型別 分配陣列變數 分配類物件
class T
{
public:
T(int _a)
{
a = _a;
cout << "建構函式執行" << endl;
}
~T()
{
cout << "解構函式執行" << endl;
}
private:
int a;
protected:
};
//分配基礎型別
//malloc/new delete/free可以混搭
int main91()
{
//C++ int型別記憶體 初始化為100
int *p = new int(100);
cout << "p:" << *p << endl;
delete p;
p = NULL;
//C語言
int *p1 = (int *)malloc(sizeof(int));
*p1 = 100;
cout << "p1:" << *p1 << endl;
free(p1); //釋放
p1 = NULL;
system("pause");
return 0;
}
//分配陣列
//malloc/new delete/free可以混搭
int main92()
{
//C語言分配陣列
int *p = (int *)malloc(sizeof(int)*10);
p[0] = 100;
cout << "p[0]:" << p[0] << endl;
free(p);
p = NULL;
//C++
int *p1 = new int[100];
p1[1] = 102;
cout << "p1[1]" << p1[1] << endl;
delete[] p1;
p1 = NULL;
system("pause");
return 0;
}
//分配物件 new delete
////malloc free 不會呼叫構造/解構函式
//new可以呼叫建構函式 delete可以呼叫解構函式
int main09()
{
//C語言
T * p = (T*)malloc(sizeof(T));
free(p);
//C++
T *p1 = new T(10);
//free(p1);
delete p1;
system("pause");
return 0;
}
5.靜態成員變數和靜態成員函式
#include <iostream>
using namespace std;
//C++類物件中的成員變數和成員函式是分開儲存的
//普通成員變數:儲存與物件中,與stuct變數有相同的記憶體佈局和位元組對齊方式
//靜態成員變數:儲存於全域性資料區
//成員函式: 儲存於程式碼段
//普通成員函式包含一個指向具體物件的指標,靜態成員變數不包含指向具體物件的指標
class Z
{
public:
void printC()
{
cout << "C:" << c << endl;
}
void addC()
{
c++;
}
//靜態成員函式,只能呼叫類的靜態成員變數
//不能使用普通成員變數
static void getC()
{
cout << "static getC:" << c << endl;
}
protected:
private:
int a;
int b;
static int c; //全部物件共同使用
};
int Z::c = 10; //設定初始值
int main10()
{
Z z1, z2, z3;
z1.printC();
z2.addC();
z1.printC();
//靜態成員函式的呼叫方法
z3.getC(); //用物件
Z::getC(); //用類名
printf("Z:%d",sizeof(Z));
system("pause");
return 0;
}
6.this指標
#include <iostream>
using namespace std;
//this是指向自身的指標
class TT
{
public:
TT(int a,int b)
{
this->a = a;
this->b = b;
}
void printT()
{
cout << "a:" << a << endl;
cout << "b:" << this->b << endl;
}
private:
int a;
int b;
protected:
};
int main()
{
TT t1(5,6);
t1.printT();
system("pause");
return 0;
}