C++基础(四) 继承和派生

1 类和类之间的关系
#include <iostream>
using namespace std;

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


// 1 包含关系 B has A
class B
{
public:
    void funcB()
    {
        a.funcA();
    }
    
    A a;
};


//2 依赖关系 C use A
class C
{
public:
    void funcB(A *a)
    {
        a->funcA();
    }
};

//3 继承关系 D extend A
class D : public A
{
public:
    void funcD()
    {
        //直接调用A类的方法
        funcA();
    }
};

int main(void){
    D d;
    d.funcA();
    return 0;
}

执行结果

funcA()
funcA()
2 继承的访问方式
#include <iostream>
using namespace std;

class Parent
{
public:
    int pub; // 类的内部和外部均可访问
public:
    int pro; // 类的内部以及子类可以,外部不可以访问
private:
    int pri; // 类的内部可以反问, 其他都不可访问
};

//1 类的公有继承
class Child1 : public Parent
{
    void func()
    {
        pub = 0;
        pro = 1;
        //pri = 2; // Error:'pri' is a private member of 'Parent'
    }
};

//2 类的保护继承
class Child2 : protected Parent
{
    void func()
    {
        pub = 0; // 此时pub 变为 pro
        pro = 1;
        //pri = 2; // Error:'pri' is a private member of 'Parent'
    }
};

//3 类的私有继承
class Child3 : private Parent
{
    void func()
    {
        pub = 0;  //4 父类的pub在此类中变为pri
        pro = 1;  //5 父类的pro在此类中变为pri
        //pri = 2; // Error:'pri' is a private member of 'Parent'
    }
};

class SubChild1 : public Child3
{
    void func()
    {
        //pub = 1; //Error:'pub' is a private member of 'Parent'
        //pro = 2; //Error:'pub' is a private member of 'Parent'
    }
};
3 类的兼容性赋值原则
#include <iostream>
using namespace std;

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

class Child : public Parent
{
public:
    void printC()
    {
        cout << "Child printC()" << endl;
    }
};

void print(Parent *p)
{
    p->printP();
}

int main(void){
    //1 子类对象可以当做父类对象使用
    Child c;
    c.printP();
    c.a = 10;
    
    //2 子类对象可以赋值给父类
    Parent p = c;
    p.printP();
    
    //3 父类指针可以指向子类对象
    Parent *pp = &c;
    cout << "pp->a = " <<  pp->a  << endl;
    
    //4 不能用子类指针指向父类对象
    //Child *cp = &p; //Error:Cannot initialize a variable of type 'Child *' with an rvalue of type 'Parent *'
    
    //5 子类引用不可以引用父类对象
    //Error:Non-const lvalue reference to type 'Child' cannot bind to a value of unrelated type 'Parent'
    //Child &cr = p;
    
    //6 父类引用可以引用子类对象
    Parent &pr = c;
    
    print(&p);
    
    print(&c);
    
    
    return 0;
}

执行结果

Parent printP()
Parent printP()
pp->a = 10
Parent printP()
Parent printP()
4 继承的构造和析构
#include <iostream>
using namespace std;

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

class Son : public Parent
{
public:
    Son(int a, int b) : Parent(a)
    {
        this->b = b;
        cout << "Son(int a, int b)" << endl;
    }
    
    ~Son()
    {
        cout << "~Son()" << endl;
    }
    
    void printB()
    {
        cout << "b= " << b << endl;
    }
    
    void printAB()
    {
        Parent::printA();
        this->printB();
    }
    
    
private:
    int b;
    char *name;
};

void test1()
{
    //1 先执行父类的构造,在执行子类的构造,
    //2 先执行子类的析构,在执行父类的析构
    Son s(20, 20);
    
    s.printAB();
}

int main(void){
    test1();
    return 0;
}

执行结果

Parent(int a)
Son(int a, int b)
a = 20
b= 20
~Son()
~Parent()
5父类和子类的成员变量重名
#include <iostream>
using namespace std;

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

class Child : public Parent
{
public:
    Child(int a, int a_p) : Parent(a_p)
    {
        this->a = a;
    }
    
    void print()
    {
        cout << "Child::a" << a << endl;
        
        //1 如果想要访问父类中的重名字段需要加上父类的作用域
        cout << "Parent :: a = "  << Parent::a << endl;
    }
    
    int a;
};

int main(void){
    Child c(10, 100);
    c.print();
    return 0;
}
Child::a10
Parent :: a100
6 派生类中的static
#include <iostream>
using namespace std;

class A
{
public:
    static int s;
};

//1 静态成员变量要在类的外部初始化
int A::s = 10;

class B:public A
{
    
};
int main(void){
    
    B b;
    cout << "b.s = " << b.s << endl;
    
    b.s = 100;
    cout << "b.s = " << b.s << endl;
    cout << "A::s = " << A::s << endl;
    return 0;
}

执行结果

b.s = 10
b.s = 100
A::s = 100
7 多继承
#include <iostream>
using namespace std;

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

//床
class Bed : public Furniture
{
public:
    void sleep()
    {
        cout << "在床上睡觉" << endl;
    }
};

//沙发
class Sofa : public Furniture
{
public:
    void sit()
    {
        cout << "在沙发上睡觉" << endl;
    }
};

//沙发床
class SofaBed : public Bed, public Sofa
{
public:
    void sitAndSleep()
    {
        sit();
        sleep();
    }
};


int main(void){
    
    Bed b;
    b.sleep();
    cout <<  "---------"   << endl;
    
    Sofa s;
    s.m = 100;
    s.sit();
    cout <<  "---------"   << endl;
    
    SofaBed sb;
    sb.sitAndSleep();
    
    return 0;
}

执行结果

在床上睡觉
---------
在沙发上睡觉
---------
在沙发上睡觉
在床上睡觉
8 虚继承

依然是上面的例子,如果不采用虚继承

class Bed :  public Furniture
class Sofa :  public Furniture

由于Fureniture中有个m变量,所以Bed和Sofa同时拥有了变量m

class Furniture
{
public:
    int m;
};

此时如果同时继承这两个类,则 Furniture 中的m则存在二义性,即不知道该继承那个类中的m

class SofaBed : public Bed, public Sofa
//二义性
//sb.m = 50; //Error: Non-static member 'm' found in multiple base-class subobjects of type 'Furniture':

解决方式: 采用虚继承,这样能让派生类中只产生一个子对象m

class Sofa : virtual public Furniture
class Bed : virtual public Furniture
//二义性--->通过虚继承解决
sb.m = 50;
cout << "sb.m = " << sb.m << endl;

执行结果

sb.m = 50
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值