多重继承、继承与组合、多文件编程实例(C++)

3.4 多重继承

C++允许一个类从一个或多个基类派生。如果一个类只有一个基类,称为单一继承。如果一个类具有两个或两个以上的基类,就称为多重继承。

class 派生类名:继承方式 基类名1, 派生方式 基类2...{
   };

在这里插入图片描述

#include <iostream>
using namespace std;

class Phone{
    //手机
private:
	string m_number;
public:
	Phone(const string& number) {
   
		m_number = number;
	}
	void call(const string& number){
   
		cout << m_number << "打给: " << number << endl;
	}
};

class Player{
    //播放器
private:
	string m_media; //播放器的名称
public:
	Player(const string& media){
   
		m_media = media;
	}
	void play(const string& music){
   
		cout << m_media << "正在播放:" << music << endl;
	}
};

class Computer{
    //电脑
private:
	string m_os; //操作系统的名称
public:
	Computer(const string& os){
   
		m_os = os;	
	}
	void run(const string& app){
   
		cout << m_os << "系统正在运行:" << app << endl;
	}
};
/* 典型的多重继承 */
class SmarePhone: public Phone, public Player, public Computer{
    //智能手机
public:
	SmarePhone(const string& number, const string& media, const string& os):Phone(number), Player(media), Computer(os){
   
	}
};

int main(void) {
   
	SmarePhone huawei("15833336666", "MP3", "鸿蒙");
	huawei.call("瑞思");
	huawei.play("我和我的祖国");
	huawei.run("4399合金弹头");
	return 0;
}

3.4.1 名字冲突

当两个不同基类拥有同名成员时,容易产生名字冲突问题。

使用作用域限定符解决。

#include <iostream>
using namespace std;

class A{
   
public:
	void func(){
   
		cout << "A func()" << endl;
	}
};

class B{
   
public:
	void func(){
   
		cout << "B func()" << endl;
	}
};

class C: public B, public A {
   
};

int main(void) {
   
	C c;
	//c.func(); //error
	c.A::func(); //加作用域限定符 来指定要访问那一个基类中的成员函数
	c.B::func();
	return 0;
}

3.4.2 钻石继承与虚继承

钻石继承,一个派生类继承的多个基类又源自一个公共的祖先(公共基类)。

在这里插入图片描述

#include <iostream>
using namespace std;

class A {
   
protected:
	int m_data;
public:
	A(int data){
   
		m_data = data;
		cout << "A(int)" << endl;
	}
};

class B: public A{
   
public:
	B(int data):A(data){
   
		cout << "B(int)" << endl;
	}
	void set(int data){
   
		m_data = data;
	}
};

class C: public A{
   
public:
	C(int data):A(data){
   
		cout << "C(int)" << endl;
	}
	int get(){
   
		return m_data;
	}
};

class D: public B, public C {
   
public:
	D(int a, int b):B(a), C(b) {
   
		cout << "D(int,int)" << endl;
	}
};
int main(void) {
   

	D d(3,6);

	cout << sizeof(D) << endl;

	cout << d.get() << endl;//6
	d.set(200);//这个位置没有起到作用
	cout << d.get() << endl;//6

	return 0;
}
//输出结果
myubuntu@ubuntu:~/lv19/cplusplus/dy03$ ./a.out 
A(int)
B(int)
A(int)
C(int)
D(int,int)
8
6
6

解决方式:虚继承

虚继承语法:

  • 在继承表使用virtual关键字修饰
  • 位于继承链表末端子类负责构造公共基类子对象
#include <iostream>
using namespace std;

class A {
   
protected:
	int m_data;
public:
	A(int data){
   
		m_data = data;
		cout << "A(int)" << endl;
	}
};

class B: virtual public A{
   
public:
	B(int data):A(data){
   
		cout << "B(int)" << endl;
	}
	void set(int data){
   
		m_data = data;
	}
};

class C: virtual public A{
   
public:
	C(int data):A(data){
   
		cout << "C(int)" << endl;
	}
	int get(){
   
		return m_data;
	}
};

class D: public B, public C {
   
public:
	D(int a, int b):B(a), C(b), A(a) {
   
		cout << "D(int,int)" << endl;
	}
};
int main(void) {
   

	D d(3,6);

	cout << sizeof(D) << endl;

	cout << d.get() << endl; //3
	d.set(200);
	cout << d.get() << endl; //200
	return 0;
}
//输出结果
myubuntu@ubuntu:~/lv19/cplusplus/dy03$ ./a.out 
A(int)
B(int)
C(int)
D(int,int)
12
3
200

3.5 继承与组合

继承与组合是C++实现代码重用的两种主要方法。

继承是ls-a的关系,比如水果和梨

组合是Has-a的关系,图书馆有图书

#include <iostream>
using namespace std;

class vehicles{
    //交通工具
public:
	void load(const string& goods) {
   
		cout << "装载" << goods << endl;
	}	
};

class tyre{
    //轮胎
public:
	void run(const string& dest){
   
		cout << "转动方向:" << dest << endl;
	}
};

class car : public vehicles{
   
public:
	tyre wheel; //轮子
};

int main(void) {
   

	car c1;
	c1.load("金枪鱼");
	c1.wheel.run("石家庄");

	return 0;
}

3.6 多文件编程实例

/*person.h*/
#ifndef __PERSON_H__
#define __PERSON_H__

#include <iostream>
using namespace std;

class Person{
   
private:
	string name;
	int age;
public:
	Person(const string& name, int age);
	void whoami();
};

#endif
/*person.cpp*/
#include "person.h"

Person::Person(const string& name, int age){
   
	this->name = name;
	this->age = age;
}

void Person::whoami() {
   
	cout << "我是:" << name << endl;
}
/*student.h*/
#ifndef __STUDENT_H__
#define __STUDENT_H__

#include "person.h"

class Student: public Person{
   
private:
	float score;
public:
	Student(const string& name, int age, float score);
	void whoami();
};

#endif 
/*student.cpp*/
#include "student.h"

Student::Student(const string& name, int age, float score):Person(name, age){
   
	this->score = score;
}
void Student::whoami() {
   
	Person::whoami();
	cout << "成绩:" << score << endl;
}
/*main.cpp*/
#include "student.h"

int main(void) {
   
	Student s1("刘铁胆", 19, 88.6);
	s1.whoami();

	return 0;
}
g++ person.cpp student.cpp main.cpp
./a.out

相关推荐

  1. C++多重继承解决方法

    2024-01-06 00:10:03       12 阅读

最近更新

  1. TCP协议是安全的吗?

    2024-01-06 00:10:03       16 阅读
  2. 阿里云服务器执行yum,一直下载docker-ce-stable失败

    2024-01-06 00:10:03       16 阅读
  3. 【Python教程】压缩PDF文件大小

    2024-01-06 00:10:03       15 阅读
  4. 通过文章id递归查询所有评论(xml)

    2024-01-06 00:10:03       18 阅读

热门阅读

  1. GIT使用简介

    2024-01-06 00:10:03       27 阅读
  2. C单词翻转

    2024-01-06 00:10:03       35 阅读
  3. uniapp 分享例子做个记录

    2024-01-06 00:10:03       39 阅读
  4. SpringBoot实用开发(十)-- MongoDB的安装

    2024-01-06 00:10:03       35 阅读
  5. 【力扣每日一题】力扣2397被列覆盖的最多行数

    2024-01-06 00:10:03       32 阅读
  6. Nginx(十六) 配置文件详解 - server stream服务流

    2024-01-06 00:10:03       37 阅读
  7. python列表的常见方法 学习笔记

    2024-01-06 00:10:03       35 阅读
  8. 【C++】知识点汇总(上)

    2024-01-06 00:10:03       32 阅读