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;
}