专业编程基础技术教程

网站首页 > 基础教程 正文

C++中继承的详细介绍以及多态的使用场景

ccvgpt 2024-10-10 05:03:43 基础教程 54 ℃

类与类之间的关系都有什么

#define _CRT_SECURE_NO_WARNINGS
#include<iostream>

using namespace std;

class A
{
public:
	void func()
	{
		cout << "funcA" << endl;
	}
	int a;
private:
};
//类B拥有类A的成员变量,  B has A// 类B 依赖于 类A
class B
{
public:
	void funcB()
	{

	}
private:
	A a;
};
//耦合度  高内聚 低耦合8
//类C的成员方法 需要类A的形参  C use A    类C 依赖于 类A
class C
{
public:
	void funcC(A*a)
	{

	}
	void funcC2()
	{

	}
private:

};

//D继承与A    A中的所有代码D都可使用   类 D is A   高耦合
class D :public A
{
public:
	void funcD()
	{
		cout << a << endl;
	}
};

class E :public D
{

};
int main()
{
	return 0;
}

继承的基本概念

继承指的是一个类继承另外的一个类,继承的类叫做子类,被继承的类叫做父类。

基本语法为:

C++中继承的详细介绍以及多态的使用场景

class A{
};
class B:public A{
};
#define _CRT_SECURE_NO_WARNINGS
#include<iostream>
#include<string>

using namespace std;

class Student
{
public:
	Student(int id, string name)
	{
		this->id = id;
		this->name = name;
	}

	void printS()
	{
		cout << "id=" << this->id << ",name=" << this->name << endl;
	}

private:
	int id;
	string name;//使用string不必担心深拷贝问题 直接拷贝即可
};

//创建一个新的类 增加score功能
class Student2
{
public:
	Student2(int id, string name, int score)
	{
		this->id = id;
		this->name = name;
		this->score = score;
	}
	void printS()
	{
		cout << "id=" << this->id << ",name=" << this->name << endl;
		cout << "score=" << this->score << endl;
	}
private:
	int id;
	string name;
	//add
	int score;
};

//通过继承创建一个新的学生类  
class Student3 :public Student//继承 Student
{
public:
	Student3(int id, string name, int score) :Student(id, name)
	{
		this->score = score;
	}
	void printS()
	{
		Student::printS();
		cout << "score=" << this->score << endl;
	}

private:
	//add
	int score;
};

int main()
{
	Student3 s3(1, "AA", 80);
	s3.printS();

	return 0;
}

几种继承方式

#define _CRT_SECURE_NO_WARNINGS
#include<iostream>

using namespace std;
//规则1.只要是父类中的private中的成员,不管是什么继承方式,儿子都无法访问
//规则2.如果是public继承,儿子中的访问控制权限保持不变。
//规则3.如果是protected继承,儿子中父亲中除了protected成员,其余在儿子中均是protected
//规则4.如果是private继承,儿子中父亲除了private成员,其余在儿子中都是private成员

class Parent
{
public:
	int pub;//类内部、外部军可发昂文
protected:
	int pro;//类内部可以访问,外部不可访问
private:
	int pri;//类内部可以访问,外部不可访问
};

//公有继承
class Child:public Parent
{
public:
	void func()
	{
		cout << pub << endl;
		//pub父类public成员变量,在public继承后类【内部、外部】均可以访问
		cout << pro << endl;
		//pro父类protected成员变量,在public继承后类【内部】可以访问
		//cout << pri << endl;//err
		//pri父类private成员变量,在public继承后【内部、外部】均不可以访问
	}

private:
};

//孙子类
class SubChild:public Child
{
public:
	void sub_func2()
	{
		cout << pro << endl;
	}
};

//保护继承
class Child2 :protected Parent
{
public:
	void func2()
	{
		pub;//此时pub通过protected继承能够在类【内部】访问
		//pub 在类的内部可以访问,类外部无法访问,类的儿子可以访问
		//pub 是protected成员
		pro;//pro与pub性质相同 pro也是protected成员
	}
private:

};
class Sub_child2:public Child2
{
public:
	void sub_func2()
	{
		pub;
		pro;
	}
};

//私有继承
class Child3 :private Parent
{
public:
	void func3()
	{
		pub;//pub在类的内部可以访问,在类的【内部】可以访问,外部不可访问。
		//pub在儿子中访问不了,说明pub在child3中是私有成员
		pro;//与pub相同
	}
};

class Sub_Child3 :public Child3
{
public:
	void sub_fun3()
	{
		//pub;//err
		//pro;//err
	}
};

int main()
{
	Child c1;
	c1.func();

	c1.pub;
	//c1.pri;//err

	Child2 c2;
	//c2.pub;//err
	//c2.pro;//err

	Child3 c3;
	//c3.pub;//err
	//c3.pro;//err

	return 0;
}

类的兼容性赋值原则

#define _CRT_SECURE_NO_WARNINGS
#include<iostream>


using namespace std;
/*
	子类对象可以当作父类对象使用。
	子类对象可以直接赋值给父类对象。
	子类对象可以直接初始化父类对象.
	****父类指针可以直接指向子类对象***
	父类引用可以直接引用子类对象
*/

class Parent
{
public:
	void printP()
	{
		cout << "a" << this->a << endl;
	}
private:
	int a;
};

class Child :public Parent
{
public:
	void printC()
	{
		cout << "b=" << this->b << endl;
	}
	int b;
};
void myPrint(Parent* pp)
{
	pp->printP();
}
int main()
{
	//	Parent p;
//	Child c = p; //p对象填充不满c对象空间,
//	Child c;
//	Parent p = c;//c 对象所占用的内存空间 >= p对象占用空间 能够填充满p对象所需要空间。
//	p = c;
//	c.printP(); //c 能够当做父类 p 来使用。
	Parent* pp = NULL;//父类指针
	Child* cp = NULL;//子类指针
	Parent p;//父类对象
	Child c; //子类对象

	pp = &c;//c 内存布局能够满足父类指针的全部需求, 可以用一个儿子的对象地址给父类指针赋值。

	myPrint(&p);
	myPrint(&c);
	return 0;
}

子类的构造和析构

#define _CRT_SECURE_NO_WARNINGS
#include<iostream>

using namespace std;

class Parent
{
public:
	Parent()
	{
		cout << "Parent().." << endl;
		a = 0;
	}
	Parent(int a)
	{
		cout << "Parent(int).." << endl;
		this->a = a;
	}
	~Parent()
	{
		cout << "~Parent" << endl;
	}
	int a;
};
class Child :public Parent
{
public:
	//在调用子类的构造函数的时候,一定会调用父类的构造函数
	Child(int a, int b):Parent(a)
	{
		cout << "Child(int ,int).." << endl;
		this->b = b;
	}
	void printC()
	{
		cout << "b=" << b << endl;
	}
	~Child()
	{ 
		cout << "~Child().." << endl;
	}
	int b;
};
int main()
{
	Child c(10, 20);
	c.printC();
	return 0;
}

当子类和父类成员重名

#define _CRT_SECURE_NO_WARNINGS
#include<iostream>


using namespace std;

class Parent
{
public:
	Parent(int a)
	{
		this->a = a;
	}
	int a;
};


class Child:public Parent
{
public:
	Child(int p_a,int c_a):Parent(p_a)
	{
		this->a = c_a;
	}
	void print()
	{
		cout << Parent::a << endl;
		cout << this->a << endl;
	}
	int a;
};

int main()
{
	Child c(10, 100);
	c.print();

	return 0;
}

继承中的static

#define _CRT_SECURE_NO_WARNINGS
#include<iostream>

using namespace std;

class A
{
public:
	static int a;
private:

};
class B :public A
{
public:
private:
};
int A::a = 100;//静态成员变量的初始化

int main()
{
	A a1;
	A a2;

	cout << a1.a << endl;
	cout << a2.a << endl;

	A::a = 200;
	cout << a1.a << endl;
	cout << a2.a << endl;

	B b1;
	B b2;
	A::a = 300;
	cout << "--------" << endl;
	cout << b1.a << endl;
	cout << b2.a << endl;
	cout << a1.a << endl;
	cout << a2.a << endl;

	return 0;
}


多继承与虚继承

#define _CRT_SECURE_NO_WARNINGS
#include<iostream>

using namespace std;

//家具类
class Furniture
{
public:
	int m;//材质
};

//virtual 虚继承  防止多子继承后出现多个爷爷中的变量重复拷贝
class Bed:virtual public Furniture
{
public:
	void sleep()
	{
		cout << "在床上睡觉" << endl;
	}
};

//虚继承
class Sofa:virtual public Furniture
{
public:
	void sit()
	{
		cout << "在沙发休息" << endl;
	}
};

//沙发床
class SofaBed:public Bed,public Sofa//多继承
{
public:
	void SleepAndSit()
	{
		sleep();
		sit();
	}
};

int main()
{
	Bed b;
	b.sleep();

	Sofa s;
	s.sit();

	cout << "----------" << endl;
	SofaBed sb;
	sb.SleepAndSit();

	sb.m = 100;      //虚继承后只有一个m
	//sb.Bed::m=100;
	//sb.Sofa::m=200;

	return 0;
}

多态

#define _CRT_SECURE_NO_WARNINGS
#include<iostream>
#include<string>

using namespace std;

//岳不群
class Yuebuqun
{
public:
	Yuebuqun( string kongfu)
	{
		this->kongfu = kongfu;
	}
	virtual void fight()//表示这是一个虚函数
	{
		cout << "岳不群"<<"使用了" << kongfu << "打人" << endl;
	}
	string kongfu;
};

//林平之
class Linpingzhi:public Yuebuqun
{
public:
	Linpingzhi(string kongfu) :Yuebuqun( kongfu)
	{
		
	}
	//
	void fight()
	{
		cout<<"岳不群"<<"使用了" << kongfu << "打人" << endl;
	}
};


class Linghuchong :public Yuebuqun
{
public:
	Linghuchong(string kongfu) :Yuebuqun(kongfu)
	{

	}
	void fight()
	{
		cout << "令狐冲" << "使用了" << kongfu << endl;
	}
};


//在全局提供一个打斗方法
void fightPeople(Yuebuqun*hero)
{
	cout << "调用打人的方法" << endl;
	hero->fight();
	//希望传进来的若是子类,调用子类fight
	//传进来的是父类,调用父类fight
	//这就是 多态 行为
}

//多态发生的三个必要条件:
//		1.要有继承
//		2.要有虚函数  (virtual)
//		3.父类指针或引用指向子类对象



int main()
{
	Yuebuqun* YY = new Yuebuqun("葵花宝典");
	YY->fight();
	delete YY;

	Linpingzhi* PP = new Linpingzhi("辟邪剑谱");
	PP->fight();
	delete PP;

	Linghuchong* LL = new Linghuchong("独孤九剑");

	fightPeople(YY);
	fightPeople(PP);
	fightPeople(LL);

	delete PP;
	return 0;
}

多态的案例和意义

#define _CRT_SECURE_NO_WARNINGS
#include<iostream>
#include<string>

using namespace std;

//英雄类
class Hero
{
public:
	virtual int getAd()
	{
		return 10;
	}

};

class AdvHero:public Hero
{
public:
	virtual int getAd()
	{
		return 1001;
	}
};

//怪兽类
class Monster
{
public:
	int getAd()
	{
		return 1000;
	}
};

//战斗方法
//版本1   写的架构函数可以调用未来
void playerFight(Hero* hp, Monster* mp)
{
	if (hp->getAd()>mp->getAd())//hp->getAd发生多态
	{
		cout << "英雄胜利" << endl;
	}
	else
	{
		cout << "英雄失败,怪兽胜利" << endl;
	}
}

//升级后 版本2
class BugHero:public Hero
{
public:
	virtual int getAd()
	{
		cout << "调用了bughero的方法" << endl;
		return 88888;
	}
};

int main()
{
	Hero h;
	
	Monster m;

	playerFight(&h, &m);

	AdvHero advH;

	playerFight(&advH, &m);

	BugHero bh;

	playerFight(&bh, &m);

	return 0;
}

虚析构函数

#define _CRT_SECURE_NO_WARNINGS
#include<iostream>

using namespace std;

class A
{
public:
	A()
	{
		cout << "A().." << endl;
		this->p = new char[64];
		memset(this->p, 0, 64);
		strcpy(this->p, "A string..");
	}
	
	virtual void print()
	{
		cout << "A: " << this->p << endl;
	}

	virtual~A()
	{
		cout << "~A().." << endl;
		if (this->p!=NULL)
		{
			delete[]this->p;
			this->p = NULL;
		}
	}

private:
	char* p;
};

class B:public A
{
public:
	B()
	{
		cout << "B().." << endl;
	}

	virtual void print()
	{
		cout << "B: " << this->p << endl;
	}

	virtual~B()
	{
		cout << "~B().." << endl;
		if (this->p!=NULL)
		{
			delete[]this->p;
			this->p = NULL;
		}
	}
private:
	char* p;
};
void func(A* ap)
{
	ap->print();//在此发生多态
	delete ap;
}
void test()
{
	A aObj;
	func(&aObj);
	B bObj;
}
int main()
{
	test();

	return 0;
}
/*
重载、重写与重定义
	1.重载 一定在同一作用域下相同函数名,不同形参列表
	2.重定义:
		发生在两个不同的类中,一个父类、一个子类
		普通函数重定义 如果父类的普通成员函数,被子类重写,就是重定义
	3.重写:虚函数重写。 
		如果父类的虚函数,被子类重写,就是虚函数重写,会发生多态。
*/

最近发表
标签列表