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