C语言到C++ 对象和类的进一步学习2

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

猜你喜欢

转载自blog.csdn.net/qq_36795563/article/details/81434391