c++继承(学习记录三)

前言


本栏主要为学习、记录c++心得所用,主要会分为三部分进行记录,欢迎评论留言,得闲会修改补充。内容如下:

  • 概念及定义;
  • 写法;
  • 程序案例。

1. 概念及定义


  • 继承:在定义一个新的类B时,如果该类与某个已有的类A相似(指的是B拥有A的全部特点),那么就可以把A作为一个基类,而B作为基类的一个派生类(也称为子类)。

  • 继承和派生的概念:派生类是通过对基类进行修改和扩充得到的;在派生类中,可以扩充新的成员变量和成员函数;此外派生类一经定义后,可以独立使用,不依赖于基类。
  • 派生类拥有基类的全部成员函数和成员变量,在派生类的各个成员函数中,不能访问基类中的private成员。
  • 继承关系和复合关系:继承为“是”关系,复合为“有“关系,具体参考 程序设计与算法–郭炜
  • 覆盖:派生类可以定义一个和基类成员同名的成员,这叫覆盖。

  • 类的保护成员, 主要有三类:private protected public
  • 直接基类与间接基类(了解):由类A派生的类B, A为B的直接基类;B到C,则A为C的间接基类。

2. 写法


class 派生类名 : public 基类名
{
    数据成员和成员函数声明;
}

/* 多重继承声明格式 */
class 派生类名: public1 基类名1, public2 基类名2,...
{
  数据成员和成员函数声明;
};
  • 复合关系的使用:
class CPoint
{
	double x, y;
}

class CCircle
{
	double r;
	CPoint center;
}
  • 作用域符号:
::
  • public继承的赋值兼容规则
class base { };
class derived : public base { };
base b;
derived d;
//派生类的对象可以赋值给基类的对象  b = d;
//派生类的对象可以初始化基类引用  base & br = d;
//派生类对象的地址可以赋值给基类指针  base * pb = & d;
//如果派生方式为:pribate / protected,则以上不可行。
  • 派生类对象的指针可以直接赋值给基类指针
Base * ptrBase = & objDerived;

ptrBase指向的是一个Derived类的对象
*ptrBase可以看作一个Base类的对象,可以通过ptrBase访问它的public成员。

3. 程序案例


  • 一个继承的简单例子
#include<string>

using namespace std;
 
class Person{
	private:
		string name;
		int age;
		char sex;
	public:
		Person():name("wl"),age(18),sex('b'){}
		Person(string c_name,int c_age,char c_sex):name(c_name),age(c_age),sex(c_sex){}
		Person(const Person &person){
			name = person.name;
			age = person.age;
			sex = person.sex;
		}
		void setName(string c_name){
			name = c_name;
		}
		string getName(){
			return name;
		}
		void setAge(int c_age){
			age = c_age;
		}
		int getAge(){
			return age;
		}
		void setSex(char c_sex){
			sex = c_sex;
		}
		char getSex(){
			return sex;
		}
		~Person();
		void print(){
			cout << name << " " << age << " " << sex << endl;
		}
    	//友元函数
		friend void show(Person b);
};
//class外声明
Person::~Person(){
	cout << "执行Person析构函数" << endl; 
}
void show(Person b){
	cout << b.name << " " << b.age << " " << b.sex << endl;
}

class Student:public Person{
	private:
		int studentId;
		string college;
	public:
		Student():studentId(1001),college("信院"){}
		Student(int c_studentId,string c_college)
			:studentId(c_studentId),college(c_college){}
		Student(string c_name,int c_age,char c_sex,int c_studentId,string c_college)
			:studentId(c_studentId),college(c_college){
			setName(c_name);
			setAge(c_age);
			setSex(c_sex);
		}
		void setStudentId(int c_studentId){
			studentId = c_studentId;
		}
		int getStudentId(){
			return studentId;
		}
		void setCollege(string c_college){
			college = c_college;
		}
		string getCollege(){
			return college;
		}
		void print(){
			cout << getName() << " " << getAge() << " " << getSex() << " " << studentId << " " << college << endl;
		}
};

class Teacher:public Person{
	private:
		int workId;
		string course;
	public:
		Teacher():workId(1001),course("C++"){}
		Teacher(int c_workId,string c_course)
			:workId(c_workId),course(c_course){}
		Teacher(string c_name,int c_age,char c_sex,int c_workId,string c_course)
			:workId(c_workId),course(c_course){
			setName(c_name);
			setAge(c_age);
			setSex(c_sex);
		}
		void setWorkId(int c_workId){
			workId = c_workId;
		}
		int getWorkId(){
			return workId;
		}
		void setCourse(string c_course){
			course = c_course;
		}
		string getCourse(){
			return course;
		}
		void print(){
			cout << getName() << " " << getAge() << " " << getSex() << " " << workId << " " << course << endl;
		}
};

class Assistant:public Student,public Teacher{
	public:
		Assistant(){}
		Assistant(string c_name,int c_age,char c_sex,int c_studentId,string c_college,string c_course){
			Student::setName(c_name);
			Student::setAge(c_age);
			Student::setSex(c_sex);
			setStudentId(c_studentId);
			setCollege(c_college);
			setCourse(c_course);
		}
		void print(){
			cout << Student::getName() << " " << Student::getAge() << " " << Student::getSex() << " " << getStudentId() << " " << getCollege() << " " << getCourse() << endl; 
 		}
};

int main(){
	//--------------------------------------------- 
	string name;
	int age;
	char sex;
	cin >> name >> age >> sex;
	//无参构造 
	Person p1;
	//传参构造 
	Person p2(name,age,sex);
	//拷贝构造 
	Person p3(p2);
	p1.print();
	p2.print();
	p3.setName("wlzs");
	p3.setAge(15);
	p3.setSex('g');
	cout << p3.getName() << " " << p3.getAge() << " " << p3.getSex() << endl;
	//--------------------------------------------- 
	Assistant as1;
	as1.print();
	Assistant as2("WzbL",21,'b',1005,"软工","高数"); 
	as2.print();
}

  • 一个王国里住着国王、他的孩子们、他的孙子们等等。每一个时间点,这个家庭里有人出生也有人死亡。
  • 这个王国有一个明确规定的皇位继承顺序,第一继承人总是国王自己。我们定义递归函数 Successor(x, curOrder) ,给定一个人 x 和当前的继承顺序,该函数返回 x 的下一继承人。
public:
    ThroneInheritance(string kingName) : king(kingName) {
    }
    
    void birth(string parentName, string childName) {
        relation[parentName].push_back(childName);
    }
    
    void death(string name) {
        deathFlag.insert(name);
    }
    
    vector<string> getInheritanceOrder() {
        vector<string> ans;
        dfs(king, ans);
        return ans;
    }

private:
    void dfs(string name, vector<string>& ans) {
        if (deathFlag.find(name) == deathFlag.end()) {
            ans.push_back(name);
        }

        for (auto& child : relation[name]) {
            dfs(child, ans);
        }
    }

private:
    string king;
    unordered_map<string, vector<string>> relation;
    unordered_set<string> deathFlag;
}
参考

  1. 程序设计与算法–郭炜
  2. 来源:力扣(LeetCode)
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值