由于最近学校开了数据结构,而且是以c++语言来描述,由于本菜鸡转专业并没有接触过c++,特此来补习一下,暂停PHP的学习。

简单立方体类设计

#include <iostream>
#include <string>
using namespace std;
class Cube{
private:
	int m_L;
	int m_H;
	int m_W;

public:
	
	//设置长宽高
	void set_L(int l)
	{
		m_L = l;
	}

	void set_H(int h)
	{
		m_H = h;
	}

	void set_W(int w)
	{
		m_W = w;
	}

	//获取长宽高
	int get_L()
	{
		return m_L;
	}

	int get_H()
	{
		return m_H;
	}

	int get_W()
	{
		return m_W;
	}

	//获取面积
	int get_area()
	{
		return 2 * (m_L * m_W + m_L * m_H + m_H * m_W);
	}

	//获取体积
	int get_volume()	
	{
		return m_W * m_L * m_H;
	}

	//	成员函数判断两个立方体是否相等
	bool isSame(Cube &c1)
	{
		if(m_H == c1.get_H() && m_W == c1.get_W() && m_L == c1.get_L())
		{
			return true;
		}
		else
			return false;
	}	
};

//全局函数判断两个立方体是否相等
/*
bool isSame(Cube &c1,Cube &c2)
{
	if(c1.get_H() == c2.get_H() && c1.get_W() == c2.get_W() && c1.get_L() == c2.get_L())
	{
		return true;
	}
	else
		return false;
}
*/


int main(int argc, char const *argv[])
{
	Cube c1,c2;
	c1.set_W(10);
	c1.set_H(10);
	c1.set_L(10);

	c2.set_W(20);
	c2.set_L(20);
	c2.set_H(20);

	cout << "c1的长宽高为:" << c1.get_L() << "," << c1.get_W() << "," << c1.get_H() << endl;
	cout << "c2的长宽高为:" << c2.get_L() << "," << c2.get_W() << "," << c2.get_H() << endl;

	cout << "c1的面积和体积:" << c1.get_area() << "," << c1.get_volume() << endl;
	
	/*
	bool is_s = isSame(c1,c2);
	if(is_s == true)
		cout << "c1和c2相等" << endl;
	else
		cout << "c1和c2不相等" << endl;
	*/

	bool is_s = c1.isSame(c2);
	if(is_s == true)
		cout << "c1和c2相等" << endl;
	else
		cout << "c1和c2不相等" << endl;

	return 0;
}

##构造函数和析构函数

初步认识

#include <iostream>
#include <string>

using namespace std;

//构造函数和析构函数
//构造函数:创建对象时自动调用
//析构函数:对象销毁时自动调用

class Person
{
	//1.1构造函数
	//没有返回值,也不用写void
	//函数名与类名相同,可以发生重载
public:
	Person()
	{
		cout << "构造函数自动调用" << endl;
	}

	~Person()
	{
		cout << "析构函数的调用" << endl;
	}
};


int main()
{
	Person p1;
}

运行结果:

构造函数的分类及调用

#include <iostream>
#include <string>

using namespace std;

/*

两种分类方式:
	1,参数分:有参构造和无参构造
	2,类型分:普通构造和拷贝构造

三种调用方法:
	1,括号法
	2,显示法
	3,隐式构造法

*/
class Person
{
	//构造函数
public:
	Person()
	{
		cout << "Person的无参构造函数调用(默认构造)" << endl;
	}
	Person(int a)
	{
		cout << "Person的有参构造函数调用" << endl;
	}

	//拷贝构造函数
	Person(const Person &p)
	{
		//将传入的对象的所有属性 拷贝到‘我’身上

		cout << "Person的拷贝构造函数调用" << endl;
	}

	
};

//调用
void test()
{
	//1,括号法

	Person p; //默认构造函数调用
	Person p1(10);//有参构造函数
	Person p2(p1);

	//2,显示法


	//3,隐式转换法
}


int main()
{
	test();
}
#include <iostream>
#include <string>

using namespace std;

/*

两种分类方式:
	1,参数分:有参构造和无参构造
	2,类型分:普通构造和拷贝构造

三种调用方法:
	1,括号法
	2,显示法
	3,隐式构造法

*/
class Person
{
	//构造函数
public:
	Person()
	{
		cout << "Person的无参构造函数调用(默认构造)" << endl;
	}
	Person(int a)
	{
		cout << "Person的有参构造函数调用" << endl;
	}

	//拷贝构造函数
	Person(const Person &p)
	{
		//将传入的对象的所有属性 拷贝到‘我’身上

		cout << "Person的拷贝构造函数调用" << endl;
	}

	
};

//调用
void test()
{
	//1,括号法

//	Person p; //默认构造函数调用
//	Person p1(10);//有参构造函数
//	Person p2(p1);

	//注意事项:调用默认构造函数的时候,不要加括号(编译器会认为是一个函数的声明)


	//2,显示法
	Person p;
	Person p2 = Person(10);
	Person p3 = Person(p2);		//等号右侧的部分叫做匿名对象:当前行执行结束后,系统会自动回收掉对象


	//3,隐式转换法
}


int main()
{
	test();
}

执行结果如上图

#include <iostream>
#include <string>

using namespace std;

/*

两种分类方式:
	1,参数分:有参构造和无参构造
	2,类型分:普通构造和拷贝构造

三种调用方法:
	1,括号法
	2,显示法
	3,隐式构造法

*/
class Person
{
	//构造函数
public:
	Person()
	{
		cout << "Person的无参构造函数调用(默认构造)" << endl;
	}
	Person(int a)
	{
		cout << "Person的有参构造函数调用" << endl;
	}

	//拷贝构造函数
	Person(const Person &p)
	{
		//将传入的对象的所有属性 拷贝到‘我’身上

		cout << "Person的拷贝构造函数调用" << endl;
	}

	
};

//调用
void test()
{
	//1,括号法

//	Person p; //默认构造函数调用
//	Person p1(10);//有参构造函数
//	Person p2(p1);

	//注意事项:调用默认构造函数的时候,不要加括号(编译器会认为是一个函数的声明)


	//2,显示法
//	Person p;
//	Person p1 = Person(10);
//	Person p2 = Person(p2);		//等号右侧的部分叫做匿名对象:当前行执行结束后,系统会自动回收掉对象


	//3,隐式转换法、
	Person p;
	Person p1 = 10;
	Person p2 = p1;
}


int main()
{
	test();
}

拷贝构造函数的调用时机

#include <iostream>
using namespace std;

//拷贝函数的调用时机

//1,使用一个已经创建完毕的对象来初始化一个新对象
//2,值传递的方式给函数参数传值
//3,值方式返回局部对象

class Person
{
public:
	Person()
	{
		cout << "Person默认构造函数调用" << endl;
	}

	Person(int age)
	{
		m_age = age;
		cout << "Person有参构造函数调用" << endl;
	}

	Person(const Person & p)
	{
		m_age = p.m_age;
		cout << "Person拷贝构造函数调用" << endl;
	}

	~Person()
	{
		cout << "Person析构函数调用" << endl;
	}
}

void method_by_exchange(Person p)
{

}


int main()
{
	
	//Person p1(20);
	//Person p2(p1);
	//cout << "p2的年龄:" << p2.m_age << endl;

//2,值传递的方式给函数参数传值
	Person p;
	method_by_exchange(p);


}

深拷贝与浅拷贝

浅拷贝带来的问题:

#include <iostream>

using namespace std;

//前置知识:当一个类初始化的时候,啥构造函数都没写,编译器自动提供默认构造和拷贝构造
//要是写了有参构造,编译器自动默认提供拷贝构造
//要是写了拷贝构造,编译器啥都不提供

class Person
{
public:

	int m_age;
	int *m_height;	//身高,用指针来做 重点关注这个值

	Person()
	{
		cout << "Person的默认构造函数调用" << endl;
	}

	Person(int age,int height)
	{
		m_age = age;
		m_height = new int(height);
		cout << "Person的有参构造函数调用" << endl;	
	}


	~Person()
	{
		if (m_height != NULL)
		{
			delete m_height;		//如果利用编译器提供的拷贝构造函数,会做浅拷贝操作
									//浅拷贝带来的问题:堆区的内存重复释放
									//如何解决???   用深拷贝来做,自己写一个拷贝构造函数
			m_height = NULL;		//double free!!!!
		}
		cout << "Person的析构函数调用" << endl;
	}

};


void test1()
{

	Person p1(3,140);
	cout << "p1的年龄为" << p1.m_age << endl;
	cout << "p1的身高为" << *p1.m_height << endl;

	Person p2(p1);
	cout << "p2的年龄为" << p2.m_age << endl;
	cout << "p2的身高为" << *p2.m_height << endl;

}


int main(int argc, char const *argv[])
{
	test1();
	return 0;
}

解决问题:深拷贝

#include <iostream>

using namespace std;

//前置知识:当一个类初始化的时候,啥构造函数都没写,编译器自动提供默认构造和拷贝构造
//要是写了有参构造,编译器自动默认提供拷贝构造
//要是写了拷贝构造,编译器啥都不提供

class Person
{
public:

	int m_age;
	int *m_height;	//身高,用指针来做 重点关注这个值

	Person()
	{
		cout << "Person的默认构造函数调用" << endl;
	}

	Person(int age,int height)
	{
		m_age = age;
		m_height = new int(height);
		cout << "Person的有参构造函数调用" << endl;	
	}

	//现在我们来写一个拷贝构造函数来解决浅拷贝问题
	Person(const Person &p)
	{
		m_age = p.m_age;
		//m_height = p.m_height       <----  这行代码是编译器自动提供的代码,会引起浅拷贝的问题

		//深拷贝操作:重新在堆区开辟一块空间!
		m_height = new int(*p.m_height);
		cout << "Person的拷贝构造函数调用" << endl;
	}


	~Person()
	{
		if (m_height != NULL)
		{
			delete m_height;		//如果利用编译器提供的拷贝构造函数,会做浅拷贝操作
									//浅拷贝带来的问题:堆区的内存重复释放
									//如何解决???   用深拷贝来做,自己写一个拷贝构造函数
			m_height = NULL;		//double free!!!!
		}
		cout << "Person的析构函数调用" << endl;
	}

};


void test1()
{

	Person p1(3,140);
	cout << "p1的年龄为" << p1.m_age << endl;
	cout << "p1的身高为" << *p1.m_height << endl;

	Person p2(p1);
	cout << "p2的年龄为" << p2.m_age << endl;
	cout << "p2的身高为" << *p2.m_height << endl;

}


int main(int argc, char const *argv[])
{
	test1();
	return 0;
}

初始化列表

#include <iostream>
using namespace std;

//作用:c++提供了初始化列表语法,用来初始化属性

class Person
{
public:
	int m_a,m_b,m_c;

public:
	/*		传统初始化操作

	Person(int a,int b,int c)
	{
		m_a = a;
		m_b	= b;
		m_c = c;
	}
	*/

	//初始化列表语法!
	Person(int a,int b,int c):m_a(a),m_b(b),m_c(c)
	{

	}

};


void test()
{
	Person p1 = Person(10,20,30);
	cout << "p1的值为:" << p1.m_a << ',' << p1.m_b << ',' << p1.m_c << endl;
}

int main(int argc, char const *argv[])
{
	test();
	return 0;
}

类和对象

类对象作为类成员

B类中有对象A作为成员,A就是对象成员
重点:观察二者的构造和析构的调用顺序

#include <iostream>
#include <string>
using namespace std;

class Phone
{	

public:

	string mpname;

	Phone(string pname)
	{
		mpname = pname;

		cout << "Phone构造函数调用" << endl;
	}

	~Phone()
	{
		cout << "Phone的析构函数调用" << endl;
	}

};




class Person
{
public:

	string mname;
	Phone mphone;
	
	//本质: Phone mphone = phone;   隐式转换法!!!
	Person(string name,string phone):mname(name),mphone(phone)
	{
		cout << "Person构造函数调用" << endl;
	}

	~Person()
	{
		cout << "Person的析构函数调用" << endl;
	}

};


void test()
{
	Person p1("tom","huawei");
	cout << "p1的值为:" << p1.mname << endl;
	cout << p1.mphone.mpname << endl;
}

int main()
{
	test();
	return 0;
}

运算符重载

加号运算符重载

作用:实现两个自定义数据类型相加的运算

实例:实现两个对象的属性值相加

#include <iostream>
using namespace std;

class Person
{
public:
	int m_A;
	int m_B;
	Person(int a,int b)
	{
		m_A = a;
		m_B = b;
	}
};


//全局函数实现重载
Person operator+(Person &A,Person &B)
{
	Person temp(0,0);
	temp.m_A = A.m_A + B.m_A;
	temp.m_B = A.m_B + B.m_B;
	return temp;
}

int main()
{
	Person p1(1,2);
	Person p2(1,2);
	Person p3 = p1 + p2;
	//本质:Person p3 = operator(p1,p2);
	cout << "p3的m_A:" << p3.m_A << endl;
	cout << "p3的m_B:" << p3.m_B << endl;
}

左移运算符重载

#include <iostream>
using namespace std;

//通过友元来访问私有属性
//左移重载运算符只能通过全局函数来实现

class Person
{
friend int main();
friend ostream &operator<<(ostream &cout,Person &p);
private:
	int m_A;
	int m_B;
};


//全局函数实现左移运算符重载
ostream &operator<<(ostream &cout,Person &p)	//本质 operator(cout , p)
{
	//cout是标准输出流的对象
	cout << "m_A:" << p.m_A << ",m_B:" << p.m_B;
	return cout; 
}

int main()
{
	Person p1;
	p1.m_A = 10;
	p1.m_B = 20;
	cout << p1;
}

递增运算符重载

分为两种:前置和后置

#include <iostream>
using namespace std;

//递增运算符重载

class MyInterger
{

friend void test();
friend ostream &operator<<(ostream &cout,MyInterger &p);

private:
	int m_Num;
public:
	MyInterger()
	{
		m_Num = 0;
	}

	//重载++运算符:前置++ 和 后置++ ,返回引用是为了一直对一个变量进行++操作
	MyInterger &operator++()
	{
		m_Num++;
		return *this;
	}


	//后置运算符重载
	//int代表占位参数,可以用于区分前置和后置递增
	MyInterger operator++(int)
	{
		//先返回结果,后递增
		MyInterger temp = *this;
		m_Num++;
		return temp;
	}

};

//左移运算符重载
ostream &operator<<(ostream &cout,MyInterger &p)
{
	cout << p.m_Num << endl;
	return cout;
}


void test01()
{
	MyInterger i;
	cout << ++(++i) << endl;	//前置运算符重载
}

void test02()
{
	MyInterger i;
	cout << i << endl;	//后置递增
}

int main()
{
	test02();
}

赋值运算符重载

c++编译器至少给一个类添加四个函数
1,默认构造
2,默认析构
3,默认拷贝构造
4,赋值运算符 operator=,对属性进行值拷贝