C++之继承、派生
创始人
2024-01-30 22:59:13
0

目录

1.继承的概念与定义

2.层次概念是计算机的重要概念:

3.私有的能被继承,不能被访问

 4.继承的三步骤

1.继承语法

2.继承例子

5.有继承和组合的构造顺序---内存布局

6.继承之下的赋值运算符重载

1.基础知识

 2.Person、Student例子

7.一个类被多个类继承


1.继承的概念与定义

继承和派生:(继承和派生一体两面)

继承(inheritance)机制:是类型层次结构设计中实现代码的复用重要手段。

class 子类: 继承权限 基类
 {
};
继承:
* 1.一个类自动拥有了来自另外一个类的属性和方法
* 2.一个类是一个类
* 层次关系-继承、派生

继承:
1、基类的处理构造和析构之外,其他的全盘继承
2、是否能被子类的成员函数访问
3、是否能被外界访问

基类的权限        public           protected         private——继承权限

 public               public            protected         private
 protected         protected      protected          private
 private             不可访问       不可访问          不可访问

派生:保持原有类特性的基础上进行扩展,增加新属性和新方法,从而产生新的类型。

在面向对象程序设计中,继承和派生是构造出新类型的过程。呈现类型设计的层次结构,体现了程 序设计人员对现实世界由简单到复杂的认识过程。

2.层次概念是计算机的重要概念:

C++ 通过类派生( class derivation)的机制来支持继承。被继承的类称为基类(base class)或超 类(superclass),新产生的类为派生类(derived class)或子类(subclass)。基类和派生类的集合 称作类继承层次结构(hierarchy)。

由基类派生出,派生类的设计形式为:

class 派生类名:访问限定符 基类名
{
private:成员表1; //派生类增加或替代的私有成员
public:成员表2; //派生类增加或替代的公有成员
protected:成员表3; //派生类增加或替代的保护成员
};//分号不可少

3.私有的能被继承,不能被访问


class A
{
public:int m_i;void print(){cout << "A::print" << endl;}
protected:int m_j;
private:int m_k;
};
class B :public A
{void set(){m_i = 10;m_j = 30;//m_k = 15;}
};
class C :protected A
{void set(){m_i = 10;m_j = 30;//m_k = 15;}
};
class D :private A
{void fn(){m_i = 10;m_j = 30;//m_k = 15;}
};
class CC :protected C
{
public:void ff(){m_i = 12;m_j = 23;//m_k = 15;}
};
class DD :public D
{
public:void ff(){//m_i = 12;//m_j = 23;//m_k = 15;}
};//如果是私有继承,只能继承,不能使用
//继承除了构造和析构全盘接收
void main()
{cout << sizeof(B) << endl;B b;b.print();b.m_i = 12;//b.m_j = 23;//b.m_k = 34;C c;//c将属性m_i变成protectedc.m_i = 12;c.m_j = 23;c.m_k = 34;}

class B :public  A//如果没有说明,默认私有继承
 //m_k = 15;//私有的能被继承,不能被访问
class DD :public D
{
public:
    void ff()
    {
        //在上一次继承被私有化了,不能再继承、访问
        //m_i = 12;
        //m_j = 23;
        //m_k = 15;
    }
};
//b.m_j = 23;//保护的在外界不能使用
C c;
//c将属性m_i变成protected
c.m_k = 34;//将C被保护继承

 4.继承的三步骤

* 1.除了构造和析构全盘接收
* 2.改写
* 3.添加子类特有的

1.继承语法

class 派生类名:[继承方式] 基类名{ 派生类新增加的成员 };

代码如下:


class A
{
public:A(){cout << "A" << endl;}void print(){cout << "A::print" << endl;}~A(){cout << "~A" << endl;}
private:int m_i;};
class B : public A
{
public:B(){cout << "B" << endl;}~B(){cout << "~B" << endl;}
private:int m_j;
};
void main()
{B b;
}

 

 因为子类继承父类的时候,先运行父类构造函数;具体的说就是运行父类时就会先“调用”父类的构造函数,注意“调用”和继承不是一个含义,实质上是“自动运行”。

2.继承例子


class Person
{
public:Person(int num,const char*name,char sex) :m_num(num), m_sex(sex){m_name = new char[strlen(name) + 1];strcpy_s(m_name, strlen(name) + 1, name);}~Person(){if (m_name != NULL){delete[]m_name;m_name = NULL;}}Person(const Person& p) :m_num(p.m_num), m_sex(p.m_sex){m_name = new char[strlen(p.m_name) + 1];strcpy_s(m_name, strlen(p.m_name) + 1, p.m_name);}void Show(){cout << m_num << " " << m_name << " " << m_sex << endl;}
private:int m_num;char* m_name;char m_sex;
};class Student :public Person
{
public:Student(int num, const char* name, char sex, float score):Person(num,name,sex),m_score(score){}Student(Student& s) :Person(s){m_score = s.m_score;}void Print(){Show();cout << m_score << endl;}
private:float m_score;
};
void main()
{Student s1(1001, "zhaowawa", 'f', 15);s1.Print();Student s2(s1);s2.Print();
}

 

 Student类公有继承了Person类中的num、name、sex,并且扩展了score。

5.有继承和组合的构造顺序---内存布局

* 1.先按照继承顺序调用基类构造
* 2.按照组合顺序调用组合的构造
* 3.调用自己的构造

class CPU
{
public:CPU() { cout << "CPU" << endl; }
};
class KB
{
public:KB() { cout << "KB" << endl; }
};
class Mouse
{
public:Mouse() { cout << "Mouse" << endl; }
};
class Computer
{
public:Computer() { cout << "Computer" << endl; }
private:CPU cpu;KB kb;Mouse ms;
}; 
class Touch
{
public:Touch() { cout << "Touch" << endl; }
};
class Laptop :public Computer
{
public:Laptop() { cout << "Laptop" << endl; }
private:Touch tc;
};
void main()
{Laptop lp;
}

1.调用基类,2.按照组合顺序得到:

CPU
KB
Mouse
Computer

3.调用自己的构造

Touch
Laptop

6.继承之下的赋值运算符重载

1.基础知识


class A
{
public:void Print(){cout << "A::Print" << endl;}
protected:int m_i;
};
/*
*隐藏:
*/
class B :public A
{
public://B::Print将A::Print隐藏了void Print(){cout << "B::Print" << endl;cout << m_i << " " << A::m_i << endl;}void set(){m_i = 10;A::m_i = 20;}
protected:int m_i;
};void main()
{A a;B b;a.Print();b.set();b.A::Print();b.Print();cout << sizeof(A) << endl;//4cout << sizeof(B) << endl;//8
}

//B::Print将A::Print隐藏了

A::Print      a.Print();
A::Print      b.A::Print();//B调用A::Print
B::Print      b.Print();
10 20         b.set();、b.Print();
4                int m_i;的大小
8                既继承了A中的m_i,B自己构造了成员

 2.Person、Student例子


class Person
{
public:Person() :m_sex('f'), m_age(20){m_name = new char[1];*m_name = '\0';cout << "Person()" << endl;}Person(const char* name,char sex,int age):m_sex(sex), m_age(age){m_name = new char[strlen(name) + 1];strcpy_s(m_name, strlen(name) + 1, name);}Person(Person& p) :m_sex(p.m_sex), m_age(p.m_age){m_name = new char[strlen(p.m_name) + 1];strcpy_s(m_name, strlen(p.m_name) + 1, p.m_name);}Person& operator=(Person& p){if (this == &p)return *this;delete[]m_name;m_name = new char[strlen(p.m_name) + 1];strcpy_s(m_name, strlen(p.m_name) + 1, p.m_name);m_sex = p.m_sex;m_age = p.m_age;return *this;}void Print(){cout << m_name << " " << m_sex << " " << m_age << endl;}~Person(){if (m_name != NULL){delete[]m_name;m_name = NULL;}}
private:char* m_name;char m_sex;int m_age;
};
class Student :public Person
{
public:Student() :m_num(0), m_score(0){cout << "Student()" << endl;}Student(int num,const char*name,char sex,int age,int score):m_num(num),Person(name,sex,age),m_score(score){}void Print(){cout << m_num << " ";Person::Print();cout << m_score << endl;}Student(Student& s) :Person(s), m_num(s.m_num), m_score(s.m_score){}Student& operator=(Student& s){if (this == &s)return *this;Person::operator=(s);m_num = s.m_num;m_score = s.m_score;return *this;}
private:int m_num;int m_score;
};
void main()
{Student s;Student s1(1001, "zhangsan", 'f', 20, 78);s.Print();s1.Print();Student s2(s1);s2.Print();s = s1;s.Print();
}

Person()                     先调用基类
Student()                    构造s对象
0  f 20                         没有给s对象赋值,为构造函数的默认值
0
1001 zhangsan f 20   打印s1对象
78
1001 zhangsan f 20   用s1对象拷贝构造s2对象,并将s2对象打印
78
1001 zhangsan f 20   将s1对象的值赋给s对象,并将s对象打印
78

为什么要给默认值?

Person() :m_sex('f'), m_age(20)
    {
        m_name = new char[1];
        *m_name = '\0';
        cout << "Person()" << endl;
    }

因为不写默认值没有指向合法的内存空间

void main()
{
    int* p;
    cout << p << endl;//error
}

7.一个类被多个类继承


class Person
{
public:Person(int num = 1000):m_num(num){}void print(){cout << "count = " << m_count << endl;}
protected:int m_num;static int m_count;
};
int Person::m_count;
class Student:public Person
{
public:Student(int num, const char*job) :Person(num){m_job = new char[strlen(job) + 1];strcpy_s(m_job, strlen(job) + 1, job);m_count++;}
private:char* m_job;
};
class Teacher :public Person
{
public:Teacher(int num, const char* job) :Person(num){m_job = new char[strlen(job) + 1];strcpy_s(m_job, strlen(job) + 1, job);m_count++;}
private:char* m_job;
};
class Worker :public Person
{
public:Worker(int num, const char* job) :Person(num){m_job = new char[strlen(job) + 1];strcpy_s(m_job, strlen(job) + 1, job);m_count++;}
private:char* m_job;
};
void main()
{Student s(1001, "student");Teacher t(1002, "teacher");Worker w(1003, "worker");w.print();s.print();Worker w1(1006, "worker");s.print();cout << sizeof(Worker) << endl;//8
}

count = 3      static成员只构造一次
count = 3      每构造一个继承了Person的对象,count++
count = 4      增加了一名Worker
8                   Person 的num+Worker的job

相关内容

热门资讯

喜欢穿一身黑的男生性格(喜欢穿... 今天百科达人给各位分享喜欢穿一身黑的男生性格的知识,其中也会对喜欢穿一身黑衣服的男人人好相处吗进行解...
发春是什么意思(思春和发春是什... 本篇文章极速百科给大家谈谈发春是什么意思,以及思春和发春是什么意思对应的知识点,希望对各位有所帮助,...
网络用语zl是什么意思(zl是... 今天给各位分享网络用语zl是什么意思的知识,其中也会对zl是啥意思是什么网络用语进行解释,如果能碰巧...
为什么酷狗音乐自己唱的歌不能下... 本篇文章极速百科小编给大家谈谈为什么酷狗音乐自己唱的歌不能下载到本地?,以及为什么酷狗下载的歌曲不是...
华为下载未安装的文件去哪找(华... 今天百科达人给各位分享华为下载未安装的文件去哪找的知识,其中也会对华为下载未安装的文件去哪找到进行解...
怎么往应用助手里添加应用(应用... 今天百科达人给各位分享怎么往应用助手里添加应用的知识,其中也会对应用助手怎么添加微信进行解释,如果能...
家里可以做假山养金鱼吗(假山能... 今天百科达人给各位分享家里可以做假山养金鱼吗的知识,其中也会对假山能放鱼缸里吗进行解释,如果能碰巧解...
四分五裂是什么生肖什么动物(四... 本篇文章极速百科小编给大家谈谈四分五裂是什么生肖什么动物,以及四分五裂打一生肖是什么对应的知识点,希...
一帆风顺二龙腾飞三阳开泰祝福语... 本篇文章极速百科给大家谈谈一帆风顺二龙腾飞三阳开泰祝福语,以及一帆风顺二龙腾飞三阳开泰祝福语结婚对应...
美团联名卡审核成功待激活(美团... 今天百科达人给各位分享美团联名卡审核成功待激活的知识,其中也会对美团联名卡审核未通过进行解释,如果能...