当前位置: 首页 > news >正文

类和对象C++

封装

将属性和行为作为一个整体,表现生活中的事物

封装的意义

#include<iostream>
#include<string.h>
using namespace std;
//设计学生类
class student {
public://公共权限

	/*
	类中的属性和行为  统一称为成员
	属性=成员属性=成员变量
	行为=成员函数=成员方法
	*/
	//属性
	string m_Name;//姓名
	int m_Id;//学号

	//权限/行为
	void setName(string name) {
		m_Name = name;
	}
	void setId(int id) {
		m_Id = id;
	}
	void showStudent() {
		cout << "name=" << m_Name << " id=" << m_Id << endl;
	}
};
int main() {
	//创建一个具体的学生——实例化对象
	student s1;
	//两种赋值方式
	//s1.m_Name = "张三";
	//s1.m_Id = 11;

	s1.setName("张三");
	s1.setId(11);

	s1.showStudent();
	return 0;
}

访问权限

公共权限 public
保护权限 protected 
私有权限 private   

#include<iostream>
using namespace std;
/*
访问权限
公共权限 public     成员类内可以访问,类外也可以访问
保护权限 protected  类内可以访问,类外不可以访问      儿子可以访问父亲中保护的内容——父亲想让儿子使用的
私有权限 private    类内可以访问,类外不可以访问      儿子不能访问父亲中私有内容——不亲不想让儿子使用的
*/

class Person {
public:
	string m_Name;

protected:
	string m_Car;

private:
	int m_Password;

public:
	void func() {
		m_Name = "张三";
		m_Car = "小米汽车";
		m_Password = 123456;
	}
};

int main() {
	Person p1;
	p1.m_Name = "张四";//可以使用
	p1.func();//可以使用
	//p1.m_Car   p1.m_Password  不能访问
	return 0;
}

struct和class的区别

#include<iostream>
using namespace std;
//struct默认权限为公共
//class默认权限为私有

class C1 {
	int m_A;//默认权限是私有
};

struct C2 {
	int m_A;//默认权限是公共
};
int main() {
	C1 c1;
	C2 c2;
	//c1.m_A;  权限是私有,不可以访问
	c2.m_A;
	return 0;
}

成员属性设置为私有

1.将所有成员属性设置为私有,可以自己控制读写权限

2.对于写权限,可以检测数据的有效性

#include<iostream>
#include<string.h>
using namespace std;
class Person {
	//提供公有的方法对私有的属性进行控制
public:
	//设置姓名
	void setName(string name) {
		m_Name = name;
	}
	//获取姓名
	string getName() {
		return m_Name;
	}
	//获取年龄
	int getAge() {
		return m_Age;
	}
	//设置年龄0~150
	void set_Age(int age) {
		if (age < 0 || age > 150) {
			cout << "年龄输入有误,赋值失败" << endl;
			return;
		}
		m_Age = age;
	}
	//设置偶像
	void set_Idol(string idol) {
		m_Idol = idol;
	}
private:
	string m_Name;//可读可写
	int m_Age = 18;//可读    也可以写(年龄必须在0-150之间)
	string m_Idol;//可写
};
int main() {
	Person p;
	p.setName("张三");
	cout << "姓名:" << p.getName() << endl;
	p.set_Age(160);
	cout << "年龄:" << p.getAge() << endl;
	p.set_Idol("卢梭");
	return 0;
}

分别用全局函数和成员函数判断两个立方体是否相等

#include<iostream>
using namespace std;
//1.设计立方体类Cube
//2.求出立方体的面积和体积
//3.分别用全局函数和成员函数判断两个立方体是否相等
class Cube {
public:
	void setLength(int l) {
		m_L = l;
	}
	int getLength() {
		return m_L;
	}
	void setWeight(int w) {
		m_W = w;
	}
	int getWeight() {
		return m_W;
	}
	void setHeight(int h) {
		m_H = h;
	}
	int getHeight() {
		return m_H;
	}
	//面积
	int getArea() {
		return 2 * m_H * m_L + 2 * m_H * m_W + 2 * m_L * m_W;
	}
	//体积
	int getVolume() {
		return m_H * m_L * m_W;
	}

	//利用成员函数判断两个立方体是否相等
	bool isSameByClass(Cube c1,Cube c2) {
		if (c1.m_H == c2.m_H && c1.m_L == c2.m_L && c1.m_W == c2.m_W)
			return true;
		else return false;
	}
private:
	int m_W;//宽
	int m_L;//长
	int m_H;//高
};

//利用全局函数判断
bool isSame(Cube &c1, Cube &c2) {
	if (c1.getLength() == c2.getLength() && c1.getHeight() == c2.getHeight() && c1.getWeight() == c2.getWeight())
		return true;
	else return false;
}

int main() {
	Cube c1;
	c1.setLength(10);
	c1.setWeight(10);
	c1.setHeight(10);
	cout << c1.getArea() << endl;
	cout << c1.getVolume() << endl;

	Cube c2;
	c2.setLength(10);
	c2.setWeight(10);
	c2.setHeight(10);

	//bool ret = isSame(c1, c2);
	bool ret = c1.isSameByClass(c1,c2);
	if (ret) cout << "c1=c2" << endl;
	else cout << "c1!=c2" << endl;
	return 0;
}

判断点和圆的位置关系

//circle.h
#pragma once
#include<iostream>
#include "point.h"
using namespace std;

class Circle {
private:
	int c_R;//半径
	Point c_Center;//圆心

public:
	void setCenter(Point center);
	//获取圆心
	Point getCenter();
	void setR(int r);
	int getR();
};

//point.h
#pragma once
#include<iostream>
using namespace std;

class Point {
private:
	int p_X;
	int p_Y;

public:
	void setX(int x);
	int getX();
	void setY(int y);
	int getY();
};

circle.cpp
#include "circle.h"
void Circle::setCenter(Point center) {
	c_Center = center;
}
//获取圆心
Point Circle::getCenter() {
	return c_Center;
}
void Circle::setR(int r) {
	c_R = r;
}
int Circle::getR() {
	return c_R;
}

//Circle::  是加上作用域

//point.cpp
#include "point.h"

void Point::setX(int x) {
	p_X = x;
}
int Point::getX() {
	return p_X;
}
void Point::setY(int y) {
	p_Y = y;
}
int Point::getY() {
	return p_Y;
}

//main
#include<math.h>
#include<iostream>
using namespace std;
#include "point.h"
#include "circle.h"

//判断点和圆的关系
void isInCircle(Circle &c,Point &p) {
	int t;
	t=pow(c.getCenter().getX() - p.getX(), 2) + pow(c.getCenter().getY() - p.getY(), 2);
	int r = c.getR();
	if(t < r*r)
		cout << "点在圆内" << endl;
	else if (t == r*r)
		cout << "点在圆上" << endl;
	else
		cout << "点在圆外" << endl;
}

int main() {
	//创建圆
	Circle c1;
	Point center;
	c1.setR(5);
	center.setX(0);
	center.setY(0);
	c1.setCenter(center);

	//创建点
	Point p;
	p.setX(3);
	p.setY(4);

	//判断关系
	isInCircle(c1, p);
	return 0;
}

.h 文件中只写声明

.cpp 文件中只写实现

把类的声明和实现分开写

 对象特征

构造函数/析构函数

#include<iostream>
using namespace std;

//对象的初始化和清理

class Person {
public:
	//1.构造函数 进行初始化
	//编译器自动调用一次
	Person() {
		cout << "Person 构造函数调用" << endl;
	}

	//2.析构函数 进行清理的操作
	//程序结束前调用
	~Person() {
		cout << "Person 析构函数调用" << endl;
	}
};
void test() {
	Person p;
}
int main() {
	test();
	//Person p;
	system("pause");
	return 0;
}

构造函数的分类及其调用

#include<iostream>
using namespace std;

//1.构造函数的分类和调用
//分类
//按照参数分类  无参构造(默认构造函数) 和  有参构造
//按照类型分类  
class Person {
public:
	int age;
	Person() {
		cout << "Person无参构造函数" << endl;
	}
	Person(int a) {
		age = a;
		cout << "Person有参构造函数" << endl;
	}
	//拷贝构造函数
	Person(const Person &p) {
		//将传入的人身上的所有属性,拷贝到我身上
		age = p.age;
		cout << "Person 拷贝构造函数" << endl;
	}
};

//调用
void test() {
	//1.括号法
	Person p1;//默认构造函数调用,不要加(),因为会认为是函数声明
	Person p2(10);
	Person p3(p2);

	//2.显示法
	Person p1;
	Person p2 = Person(10);//有参构造
	Person p3 = Person(p2);//拷贝构造

	//Person(10); //匿名对象 特点:当前行执行结束后,系统会立即回收掉匿名对象
	//cout << "aaa" << endl;

	//不要利用拷贝构造函数 初始化匿名对象。编译器会认为是声明

	//3.隐式转换法
	Person p4 = 10;  //相当于 Person p4 = Person(10);
	Person p5 = p4; //拷贝构造
}
int main() {
	test();
	system("pause");
	return 0;
}

构造函数调用规则 

 深拷贝/浅拷贝

初始化列表 

#include<iostream>
using namespace std;
//初始化列表
class Person {
public:
	//传统初始化操作
	/*Person(int a,int b,int c) {
		m_A = a;
		m_B = b;
		m_C = c;
	}*/

	//初始化列表
	/*Person() :m_A(10), m_B(20), m_C(30) {

	}*/
	Person(int a,int b,int c) :m_A(a), m_B(b), m_C(c) {

	}

	int m_A;
	int m_B;
	int m_C;
};

void test01() {
	//Person p(10, 20, 30);//创建对象

	//Person p;

	Person p(30, 20, 10);

	cout << "m_A=" << p.m_A << endl;
	cout << "m_B=" << p.m_B << endl;
	cout << "m_c=" << p.m_C << endl;
}

int main() {
	test01();

	system("pause");
	return 0;
}

类对象作为类成员

#include<iostream>
#include<string.h>
using namespace std;
//类对象作为类成员
//B类中有对象A作为成员,A为对象成员

//手机类
class Phone {
public:
	//手机品牌名称
	string m_PName;

	Phone(string pName) {
		m_PName = pName;
		cout << "Phone的构造函数调用" << endl;
	}
};
//人类
class Person {
public:
	//姓名
	string m_Name;
	//手机
	Phone m_Phone;

	//隐式转换
	Person(string name, string pName):m_Name(name),m_Phone(pName)
	{
		cout << "Person的构造函数调用" << endl;
	}
};

//测试案例
void test01() {
	Person p("张三", "华为");
	cout << p.m_Name << "拿着" << p.m_Phone.m_PName << "手机" << endl;
}
int main() {
	test01();
	//system("pause");
	return 0;
}

 静态成员 static

静态成员变量/静态成员函数

#include<iostream>
using namespace std;

class Person {
public:
	//1.所有对象都共享同一份数据
	//2.编译阶段就分配内存
	//3.类内声明,类外初始化操作
	static int m_A;

	//静态成员变量访问权限
private:
	static int m_B;
};

int Person::m_A = 100;//Person作用域下
int Person::m_B = 4;

void test01() {
	Person p;
	cout << p.m_A << endl;//100

	Person p2;
	p2.m_A = 200;
	cout << p.m_A << endl;//200  m_A是共享的
}

void test02() {
	//静态成员变量 不属于某个对象上,所有对象都共享同一份数据
	//因此静态成员变量有两种访问方式

	//1.通过对象进行访问
	Person p;
	cout << p.m_A << endl;

	//2.通过类名进行访问
	cout << Person::m_A << endl;

	//cout << Person::m_B << endl; //报错,私有权限类外不能访问
}
int main() {
	//test01();
	test02();
	system("pause");
	return 0;
}

C++对象模型和this指针

成员变量和成员函数分开存储

#include<iostream>
using namespace std;
//成员变量和成员函数分开存储

//*只有非静态成员变量才属于类的属性上
class Person {

};

void test01() {
	Person p;
	//空对象占用内存空间为:1
	//为了区分空对象占内存的位置
	//每个空对象也应该有一个独一无二的内存地址
	cout << "size of p= " << sizeof(p) << endl;
}

void test02() {
	int m_A;//非静态成员变量  属于类的对象 大小为4

	static int m_B;//静态成员变量 不属于类的对象上 加上它还是4

	//void func() {} //非静态成员函数 不属于类的对象 还是4

	//静态成员函数 不属于类的对象
}

int main() {
	test01();
	system("pause");
	return 0;
}

this指针

谁调用它,就指向谁

#include<iostream>
using namespace std;

class Person {
public:
	Person(int age) {
		//this指针指向的是 被调用的成员函数所属的对象
		this->age = age;
	}
	int age;

	Person& PersonAddAge(Person &p) {
		this->age += p.age;
		//返回对象指针
		return *this;
	}
};

//1.解决名称冲突
void test01() {
	Person p1(18);
	cout <<"p1的年龄为:" << p1.age << endl;
}

//2.返回对象本身用 *this
void test02() {
	Person p1(10);
	Person p2(10);

	//链式编程思想 p2 = p2+p1+p1+p1
	p2.PersonAddAge(p1).PersonAddAge(p1).PersonAddAge(p1);

	cout << "p2的年龄为:" << p2.age << endl;
}

int main() {
	test01();
	test02();
	system("pause");
	return 0;
}

空指针访问成员函数

#include<iostream>
using namespace std;
//空指针调用成员函数

class Person {
public:
	void showClassName() {
		cout << "this is Person class" << endl;
	}

	void showPersonAge() {
		//报错原因是因为传入的指针是NULL
		if (this == NULL)
			return;
		cout << "age=" << m_Age << endl;
	}
	int m_Age;
};

void test01() {
	Person* p = NULL;
	p->showClassName();
	p->showPersonAge();
}

int main() {
	test01();
	system("pause");
	return 0;
}

const修饰成员函数

 const 加的位置

加mutable 使之可以修改

友元

#include<iostream>
#include<string.h>
using namespace std;
//友元的目的就是让一个函数或者类 访问另一个类中私有成员
//友元的关键字为 friend
//友元的三种实现
//1.全局函数做友元
//2.类做友元
//3.成员函数做友元

class Building
{
	friend void goodGay(Building* building);//声明放类里,前面加上friend
public:
	Building()//类内写成员函数
	{
		m_SittingRoom = "客厅";
		m_BedRoom = "卧室";
	}
public:
	string m_SittingRoom;//客厅
private:
	string m_BedRoom;//卧室
};

//1.全局函数做友元
void goodGay(Building* building)//指针
{
	cout << "好朋友全局函数 正在访问:" << building->m_SittingRoom << endl;
	cout << "好朋友全局函数 正在访问:" << building->m_BedRoom << endl;
}

int main() {
	Building building;
	goodGay(&building);
	system("pause");
	return 0;
}

 运算符重载

对已有的运算符重新进行定义,赋予其另一种功能,以适应不同的数据类型

加法运算符重载

#include<iostream>
using namespace std;
//对已有的运算符重新进行定义,赋予其另一种功能,以适应不同的数据类型

//加号运算符重载
//实现任意类型的数相加
//1.通过成员函数重载+号
//2.通过全局函数重载+号

class Person
{
public:
	//1.通过成员函数重载+号
	/*Person operator+(Person& p)
	{
		Person temp;
		temp.m_A = this->m_A + p.m_A;
		temp.m_B = this->m_B + p.m_B;
		return temp;
	}*/

	int m_A;
	int m_B;
};

//2.通过全局函数重载+号
Person operator+(Person& p1, Person& p2)
{
	Person temp;
	temp.m_A = p1.m_A + p2.m_A;
	temp.m_B = p1.m_B + p2.m_B;
	return temp;
}

void test01()
{
	Person p1;
	p1.m_A = 1;
	p1.m_B = 2;
	Person p2;
	p2.m_A = 3;
	p2.m_B = 4;

	Person p3 = p1 + p2;

	cout << "p3.m_A=" << p3.m_A << endl;
	cout << "p3.m_B=" << p3.m_B << endl;
}

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

 左移运算符重载

#include<iostream>
using namespace std;
//左移运算符重载

class Person
{
	friend ostream& operator<<(ostream& cout, Person& p);
public:
	Person(int a, int b)
	{
		m_A = a;
		m_B = b;
	}
private:
	//利用成员函数重载 左移运算符
	int m_A;
	int m_B;
};

//只能利用全局函数重载左移运算符
ostream & operator<<(ostream &cout,Person &p)//本质 operator<<(cout,p) 简化 cout<<p
{
	cout << "m_A=" << p.m_A << " m_B=" << p.m_B;
	return cout;
}

void test01()
{
	Person p(2, 3);
	cout << p << endl;;
}
int main() {
	test01();
	system("pause");
	return 0;
}

 递增/赋值/关系/函数调用运算符重载

继承

语法          class 子类 :继承方式 父类

继承方式:public、protected、private

子类=派生类

父类=基类

#include<iostream>
using namespace std;

class base1 {
public:
	int m_A;
protected:
	int m_B;
private:
	int m_C;
};

class son1 : public base1 {
public:
	void fun() {
		m_A = 10;
		m_B = 10;
		//m_C = 10; 私有儿子不能访问
	}
};

class son2 :protected base1 {
public:
	void fun() {
		m_A = 10;//父类中 public成员,到子类中变为保护权限
		m_B = 10;
		//m_C = 10; 私有儿子不能访问
	}
};

class son3 :private base1 {
public:
	void fun() {
		m_A = 10;//父类中 public成员,到子类中变为 private成员
		m_B = 10;
		//m_C = 10; 私有儿子不能访问
	}
};

class GrandSon3 :public son3 {
public:
	void fun() {
		//m_A = 10; m_B = 10; 私有,son3的儿子GrandSon3不能访问
	}
};

void text01() {
	son1 s1;
	s1.m_A = 100;
	//s1.m_B   到 son1中 m_B是保护权限 类外访问不到

	son2 s2;
	//s2.m_A  s2.m_B 到 son1中m_A、m_B是保护权限 类外访问不到

	son3 s3;
	//s3.m_A  s3.m_B 到 son3中m_A、m_B是私有成员
}

int main() {
	text01();
	system("pause");
	return 0;
}

//父类中所有非静态成员属性都会被子类继承下去
//父类中private成员属性 是被编译器隐藏了 但继承下去了

多继承

#include<iostream>
using namespace std;

class Base1 {
public:
	Base1(){
		m_A = 100;
	}
	int m_A;
};

class Base2 {
public:
	Base2() {
		m_A = 200;
	}
	int m_A;
};

//多继承--继承多个父类
class Son : public Base1 , public Base2{
public:
	Son() {
		m_C = 300;
		m_D = 400;
	}
	int m_C;
	int m_D;
};

void text01() {
	Son s;
	cout << sizeof(s) << endl;//16
	//父类中出现同名成员,需要加作用域区分
	cout << s.Base1::m_A << endl;
}

int main() {
	text01();
	//system("pause");
	return 0;
}

菱形继承

继承之前 加上关键字 virtual变为虚继承 

#include<iostream>
using namespace std;
//菱形继承

//动物类
class Animal {
public:
	int m_Age;
};

//利用虚继承可以解决菱形继承的问题
// 继承之前 加上关键字 virtual变为虚继承
// Animal类称为 虚基类
//羊类
class Sheep : virtual public Animal {};

//驼类
class Tuo :virtual public Animal {};

//羊驼类
class SheepTuo :public Sheep, public Tuo {};

void text01() {
	SheepTuo st;
	st.Sheep::m_Age = 18;
	st.Tuo::m_Age = 28;
	cout << st.Sheep::m_Age << endl;
	cout << st.Tuo::m_Age << endl;
	cout << st.m_Age << endl;
	//这个数据只需要一份
}

int main() {
	text01();
	//system("pause");
	return 0;
}

多态

一个接口有多种形态

#include<iostream>
using namespace std;
//动态多态:派生类和虚函数实现运行时多态
//晚绑定--运行阶段确定函数地址


//动态多态满足条件
//1.有继承关系
//2.子类重写父类的虚函数

//动态多态使用
//父类的指针或者引用 执行子类对象
class Animal {
public:
	//虚函数
	virtual void speak() {
		cout << "动物说话" << endl;
	}
};

class Cat : public Animal{
public:
	//重写  函数返回值类型 函数名 参数列表 完全相同
	void speak() {
		cout << "小猫说话" << endl;
	}
};

class Dog : public Animal {
public:
	void speak() {
		cout << "小狗说话" << endl;
	}
};

//说话函数
void doSpeak(Animal &animal) {
	animal.speak();
}

void test() {
	Cat cat;
	doSpeak(cat);

	Dog dog;
	doSpeak(dog);
}

int main() {
	test();
	return 0;
}
#include<iostream>
#include<string.h>
using namespace std;
//多态的优点
//1.代码组织结构清晰
//2.可读性强
//3.利于前期和后期的扩展以及维护

//分别利用普通写法和多态技术实现计算器

//普通写法
class Calculator {
public:
	int GetResult(string oper) {
		if (oper == "+")
			return m_Num1 + m_Num2;
		else if (oper == "-")
			return m_Num1 - m_Num2;
		else if (oper == "*")
			return m_Num1 * m_Num2;
		else if (oper == "/")
			return m_Num1 / m_Num2;
	}
	int m_Num1;
	int m_Num2;
};

void test01() {
	Calculator c;
	c.m_Num1 = 10;
	c.m_Num2 = 2;
	cout << c.m_Num1 << "+" << c.m_Num2 << "=" << c.GetResult("+") << endl;
	cout << c.m_Num1 << "-" << c.m_Num2 << "=" << c.GetResult("-") << endl;
	cout << c.m_Num1 << "*" << c.m_Num2 << "=" << c.GetResult("*") << endl;
	cout << c.m_Num1 << "/" << c.m_Num2 << "=" << c.GetResult("/") << endl;
}

//多态写法
//实现计算器抽象类
class AbstractCalculator {
public:
	virtual int getResult() {//父类有抽象方法
		return 0;
	}
	int m_Num1;
	int m_Num2;
};

//加法计算器类
class AddCalculator : public AbstractCalculator {//子类有继承
public:
	int getResult() {//重写父类抽象方法
		return m_Num1 + m_Num2;
	}
};

//减法计算器类
class SubCalculator : public AbstractCalculator {
public:
	int getResult() {
		return m_Num1 - m_Num2;
	}
};

void test02() {
	//多态使用条件
	//父类指针或者引用指向子类对象
	
	//加法
	AbstractCalculator* abc = new AddCalculator;//父类指针
	abc->m_Num1 = 3;
	abc->m_Num2 = 5;
	cout << abc->m_Num1 << "+" << abc->m_Num2 << "=" << abc->getResult() << endl;
	//用完要销毁
	delete(abc);

	//减法
	abc = new SubCalculator;
	abc->m_Num1 = 4;
	abc->m_Num2 = 3;
	cout << abc->m_Num1 << "-" << abc->m_Num2 << "=" << abc->getResult() << endl;
	delete(abc);
}

int main() {
	//test01();
	test02();
	return 0;
}

纯虚函数和抽象类

#include<iostream>
using namespace std;
//纯虚函数和抽象类
class Base {
	//抽象类
	//1.无法实例化对象
	//2.抽象类的子类 必须要重写父类中的纯虚函数
public:
	virtual void func() = 0;//纯虚函数语法
};

class Son : public Base {
public:
	virtual void func() {
		cout << "func" << endl;
	}
};
void test01() {
	//Base b;  抽象类无法实例化对象
	Son s;
	Base* base = new Son;//创建子类对象
	base->func();//调用子类的函数
}
int main() {
	test01();
	return 0;
}
#include<iostream>
using namespace std;
//制作饮品
class AbstractDrinking {
public:
	//煮水
	virtual void Boil() = 0;
	
	//冲泡
	virtual void Brew() = 0;

	//倒入杯中
	virtual void PourInCup() = 0;

	//加入辅料
	virtual void PutSomething() = 0;

	//制作饮品
	void makeDrink() {//函数调用具体的实现
		Boil();
		Brew();
		PourInCup();
		PutSomething();
	}
};

class Coffee :public AbstractDrinking {
public:
	//煮水
	virtual void Boil() {
		cout << "煮矿泉水" << endl;
	};

	//冲泡
	virtual void Brew() {
		cout << "冲泡咖啡" << endl;
	};

	//倒入杯中
	virtual void PourInCup() {
		cout << "倒入杯中" << endl;
	};

	//加入辅料
	virtual void PutSomething() {
		cout << "加入糖" << endl;
	};
};

class Tea : public AbstractDrinking {
public:
	//煮水
	virtual void Boil() {
		cout << "煮山泉水" << endl;
	};

	//冲泡
	virtual void Brew() {
		cout << "冲泡茶叶" << endl;
	};

	//倒入杯中
	virtual void PourInCup() {
		cout << "倒入杯中" << endl;
	};

	//加入辅料
	virtual void PutSomething() {
		cout << "加入柠檬" << endl;
	};
};

void doWork(AbstractDrinking* abs) {
	abs->makeDrink();//调用父类中的函数
	delete abs;//释放
}

void test01() {
	doWork(new Coffee);
	cout << "-------------" << endl;
	doWork(new Tea);
}

int main() {
	test01();
	return 0;
}
#include<iostream>
#include<string.h>
using namespace std;
//虚析构和纯虚析构

class Animal {
public:
	Animal() {
		cout << "Animal构造函数调用" << endl;
	}
	//虚析构 可以解决父类指针释放子类对象不干净的问题
	/*virtual ~Animal() {
		cout << "Animal析构函数调用" << endl;
	}*/
	//纯虚析构
	virtual ~Animal() = 0;//声明
	//纯析函数
	virtual void speak() = 0;

};

//具体实现
Animal::~Animal() {
	cout << "Animal纯虚析构函数调用" << endl;
}

class Cat :public Animal {
public:
	Cat(string name) {
		m_Name = new string(name);//堆区创建属性
		cout << "Cat构造函数调用" << endl;
	}
	virtual void speak() {
		cout <<*m_Name<< "猫说话" << endl;
	}
	~Cat() {//析构函数释放堆区数据
		if (m_Name != NULL) {
			cout << "Cat析构函数调用" << endl;
			delete m_Name;
			m_Name = NULL;
		}
	}
	string *m_Name;//猫名字,指针
};

void test01() {
	Animal* animal = new Cat("咪咪");//创建一个具体的猫对象
	animal->speak();//调用说话函数
	delete animal;
}

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

相关文章:

  • 鸿蒙数据持久化之首选项
  • WebGL学习2
  • Echarts 折线图
  • 【Linux笔记】动态库与静态库的理解与加载
  • 《数字图像处理》第三章 灰度变换与空间滤波学习笔记(3.1-3.2)反转、对数、幂律、分段线性等变换
  • 【QT:QSS】
  • 在 MySQL 中,只写 JOIN 等价于?
  • linux 命令 mkdir
  • Spring中DI与IOC的关系解析
  • 卷积神经网络 - 卷积层(具体例子)
  • 第六节 MATLAB M-Files
  • MySQL 关联查询知识
  • 网络篇--网络基础
  • Fortinet全新下一代防火墙NGFW
  • LS-NET-008-OSPF、BGP、RIP三大路由协议
  • 【css酷炫效果】纯CSS实现黑白电视故障雪花
  • 腾讯云容器集群:节点可以访问公网,节点内的pod无法访问公网
  • 【RabbitMQ】RabbitMQ消息的重复消费问题如何解决?
  • Oracle 19c 子分区表索引测试
  • v-自定义权限指令与v-if互相影响导致报错Cannot read properties of null (reading ‘insertBefore‘)
  • Java电商网站开发服务端/bt蚂蚁磁力
  • 如何做自己的论坛网站/国内10大搜索引擎
  • 上饶网站建设srsem/关键字排名优化公司
  • 网站设计的目的是什么/信息流广告优秀案例
  • 郴州做网站/深圳网站建设 手机网站建设
  • 做算命网站挣钱么/seo品牌优化