c++类

 类的定义

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

//class 的限令符:public 公共的,protected 受保护的,private 私有的
class Coordinate {
public:
	void addrun(int x, int y) {
		int_x = x;
		int_y = y;
	}
	int get_run() {
		return int_x + int_y;
	}
	int int_x;
	int int_y;
};
//class类有两种实例化对象的方法:分别有

int main01() {
	//1.从栈中实例化对象,栈中实例化对象会自动释放掉
	Coordinate Coor;//定义在栈中的对象
	Coor.addrun(20, 30);
	Coor.int_x = 50;
	cout << Coor.get_run() << endl;

	//2.从堆中实例化对象,也就是定义指针去实例化
	Coordinate * p = new Coordinate();
	if (p == NULL) {
		return 0;//判断是否申请内存成功
	}
	p->int_x = 80; //访问类中的成员
	p->int_y = 120;
	cout << p->get_run() << endl; //访问类中定义的函数
	delete p; // 释放掉 p 申请的内存
	p = NULL; // 把指针 p 设置成空指针
	//到这里堆的实例化才算完
	system("pause");
	return 0;
}

分文件处理

#include "Teacher.h"
以下就是类外定义了,也就是将函数的方法定义到了外边,在类中申明有这么个函数
分文件类外定义也是差不多的,也就是将类放到了 .h 的头文件中
将类外的那些方法定义到另外一个cpp文件中,但是必须要引用这个 .h 文件
到时候主文件调用也是调用.h文件

#include <iostream>
#include <string>
#include "stdlib.h"
using namespace std;

class Teacher {
public:
	void setName(string name);
	string getName();
	void setGender(string gender);
	string getGender();
	void setAge(int age);
	int getAge();
	void teach();
private:
	string var_name;
	string var_gender;
	int var_age;
};
//
#include "Teacher.h"
void Teacher::setName(string name) {
	var_name = name;
}
string Teacher::getName() {
	return var_name;
}
void Teacher::setGender(string gender) {
	var_gender = gender;
}
string Teacher::getGender() {
	return var_gender;
}
void Teacher::setAge(int age) {
	var_age = age;
}
int Teacher::getAge() {
	return var_age;
}
void Teacher::teach() {
	cout << "快了" << endl;
}

构造函数初始化列表

构造函数初始化列表//
默认构造函数
初始化列表的特性:
初始化列表先于构造函数执行
初始化列表只能用于构造函数
初始化列表可以同时初始化多个数据成员

初始化列表存在的必要性
我们定义一个类,比如一个圆的类


class Coor {
public:
	Coor() { m_dPi = 3.14; }
private:
	const double m_dPi;
};
上面的那个代码是有错误的,因为const修饰的变量不能改变,然后在构造函数中给变量赋值了,所以就会报错
//这个时候就能体现出我们初始化列表的必要性了
//初始化列表的代码演示:
class Coor {
public:
	Coor():m_dPi(3.14){}//m_dPi(3.14) 是初始化的列表,这样就不会再报错了
private:
	const double m_dPi;
};

构造函数

/**

* 定义类:Student

* 数据成员:m_strName

* 无参构造函数:Student()

* 有参构造函数:Student(string _name)

* 拷贝构造函数:Student(const Student& stu)

* 析构函数:~Student()

* 数据成员函数:setName(string _name)、getName()

*/

class Student {
public:
	Student() { 
		m_strName = "jim"; 
		cout << "默认构造函数,调用这个类的时候无需参数就自动调用!" << endl;
	}
	Student(string name){ 
		m_strName = name; 
		cout << "需要参数的构造函数!" << endl;
	}
	/*Student(string name):m_strName(name){
		cout << "初始化列表,数据成员用了const修饰之后必须要用的!" << endl;
	}*/
	/*Student(const string name) {
		m_strName = name; 
		cout << "拷贝构造函数,在类调用被拷贝的时候调用" << endl;
	}*/
	~Student() { cout << "系统销毁时自动调用到我了!必须是无参数的,不能重载" << endl; }
	void setName(string name) {
		m_strName = name;
	}
	string getName() {
		return m_strName;
	}
private:
	//const string m_strName;
	string m_strName;
};

 

this 指针指向被调用的成员函数所属的对象
this 指针是隐含每一个非静态成员函数所属的对象
this不需要定义直接用就可以


this指针的用途
当形参和成员变量同名时,可以用this来解决
在类的非静态成员函数中返回对象本身,return *this

class Proson {
public:
	Proson(int age) {
		this->age = age;
	}
	int Show() {
		return age;
	}
	Proson& ProsonAdd(Proson& p) {
		//Proson& p 把一个对象传进来,在这里就可以直接调用这个对象里面的属性了
		this->age += p.age;
		return *this;//返回这个对象的本身,定义函数的返回值必须是Proson&地址
	}
private:
	int age;//这个名字和构造函数中的参数同名了,会报错,加上this就指向就可以 解决
};

void test01() {
	Proson p1(10);
	cout << p1.Show() << endl;
}

//return *this
void test02() {
	Proson p1(10);
	Proson p2(10);
	//Proson返回这个对象的本身之后,我们就又可以直接的调用这个对象里面的函数成员了
	p2.ProsonAdd(p1).ProsonAdd(p1).ProsonAdd(p1);
	cout << p2.Show() << endl;
}



int main_this() {
	test02();
	system("pause");
	return 0;

}

 

const修饰成员函数

#include <iostream>
using namespace std;

///常函数:
///1.成员函数后加上const之后,我们称这个函数为常函数
///2.常函数内不可以修改成员属性
///3.成员属性申明时加上mutable,在常函数中依然可以修改

class Proson {
	public:

		/*
		常函数加上了const之后,也就相当于 const Proson * const this
		修饰的是this
		这样 this->m_A值也就不能在更改了,指针被修饰,常量也被修饰了,都不能改
		*/
		void ShowProson() const{
			//this = NULL; //this是一个指针常量,也就是指向的地址不能改变,指向的值可以改变
			m_A = 100;//加上了const之后变成了常函数,就不能这样修改成员属性值了
			
		}
		mutable int m_B;
		int m_C;
	private:
		//int m_A;//没有给成员属性前面加上mutable,在ShowProson常函数中能修改这个值
		mutable int m_A;//特殊变量,即使在常函数中也是可以修改属性值的
};



///常对象:
///1.对象前加上const之后,叫常对象
///2.常对象只能调用常函数
void test04() {
	const Proson p;//常函数
	//p.m_C=100; 这个就报错了,因为是一个常对象,只能调用常函数,和加上mutable关键字的成员属性
	p.m_B = 100;//必须要在公共区域
	p.ShowProson();
}

int main03() {

	system("pause");
	return 0;
}

 

类继承,有三种继承方式:public 公共的,protected 受保护的,private 私有的

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

class Publico {
public:
	void Public_all() {
		cout << "我是全部的内容" << endl;
	}
};

class Java :public Publico{
public:
	void Javas() {
		cout << "Java" << endl;
	}
};
class Python :public Java {
public:
	void Pythons() {
		cout << "python" << endl;
	}
};


int test() {
	Java* java = new Java();
	Python* python = new Python();
	if (java == NULL) {
		return 0;
	}
	if (python == NULL) {
		return 0;
	}
	java->Javas();
	java->Public_all();
	cout << "*************************" << endl;
	python->Pythons();
	python->Public_all();
	cout << "以下是python类调用的" << endl;
	python->Javas();
	delete python;
	delete java;
	python = NULL;
	java = NULL;
	
}
int main_() {
	test();
	system("pause");
	return 0;
}

 

多态继承

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


//多继承的菱形多继承问题
//动物类
class Animalia 
{
public:
	int Age;
};

//羊类,继承了动物类
class Sheep:virtual public Animalia
{
public:
	int Age;
};
//陀类,继承了动物类
class Tuo:virtual public  Animalia
{
public:
	int Age;
};
//羊驼类,继承了陀类和羊类
class Alpaca :public Sheep, public Tuo {
public:
	void print() {
		//cout << Age << endl;//继承了两个age,就会报错了
		//可以使用作用域来解决,但是我们只需要一份数据就行了
		//这时候我们可以使用虚继承来解决这个问题
		//使用virtual关键词,public为继承方式
		//在基类上的语法是 class name:virtual public _name
	}
};
void Alpaca_fun() {
	Alpaca alp;
	alp.Sheep::Age = 18;
	alp.Tuo::Age = 28;
	//当发生了虚继承之后,他们的数据也就只有一份,取最后赋值
	cout << "alp.Sheep::Age = " << alp.Sheep::Age << endl;
	cout << "alp.Tuo::Age = " << alp.Tuo::Age  << endl;

}

///多态的虚函数

class Animalia2 {
public:
	virtual void print() {
		cout << "This is animal" << endl;
	}
};

class Cat:public Animalia2 {
public:
	void print() {
		cout << "This is Cat" << endl;
		//当子类重写父类中的函数,子类的虚函数表内部会替换成子类的虚函数地址,也就是覆盖掉了父类中的函数
	}
};

class Dog :public Animalia2 {
public:
	void print() {
		cout << "This is Dog" << endl;
	}
};


//当父类的指针或者引用指向子类对象的时候发生多态
void Animalia2_son(Animalia2 & animalia2)
//这是一个引用,Animalia2 & animalia2 = dog,父类的引用指向子类dog对象
{
	animalia2.print();
	//1.在基类Animalia基类中的函数没有变成虚函数之前,这里不管是传入的是哪一个对象打印的都是基类中的函数
	//没有使用virtual是地址早绑定,在编译阶段确定了函数的地址
	//2.如果想要的地址是动态绑定的就在父类中的函数加入virtual关键字,子类可以加野可以不加
	//定义了父类中加上virtual之后,子类中相同函数就发生了重写
}

int main_0() {
	Dog dog;
	Cat cat;
	Animalia2_son(dog);
	//Alpaca_fun();
	system("pause");
	return 0;
}

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

CID( ͡ _ ͡°)

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值