C++ 类继承(廿一)--基类、派生类、多态继承、公有继承、私有继承、虚函数、保护继承、多重继承




概念:创建派生类对象时,程序首先调用基类的构造函数,然后再调用派生类的构造函数。基类构造函数负责初始化继承的数据成员,派生类构造函数主要用于初始化新增的数据成员。派生类构造函数总是调用一个基类构造函数。可以使用初始化列表语法指明要使用的基类构造函数,否则使用默认的基类构造函数。


C++三种继承方式:公有继承、私有继承、保护继承


特殊关系:1、派生类可以调用基类的方法,前提不是私有函数;

           2、基类指针可以不进行显式类型转换下指向派生类对象;

3、基类引用可以不进行显式类型转换下引用派生类对象;

4、基类指针或用引用只能调用基类方法。

注意:不能将基类引用和地址赋值给派生类对象和地址




TablePlayer.hpp

#ifndef TablePlayer_hpp
#define TablePlayer_hpp

#include <stdio.h>
#include <string>
#include <iostream>

using namespace std;

class TablePlayer {
    
private:
    string firstName;
    string lastName;
    bool   hasTable;
    
public:
    //成员初始化列表语法(如果调用时不传实参,则使用默认值),构造函数,用引用&可以减少创建新变量占用内存及提高速度
    TablePlayer(const string &fn = "dadf", const string &ln = "nono",bool bl = false);
    //如果析构函数不作任何处理,可以忽略不写
    ~TablePlayer(){}
    
    void Name();
    bool HasTable(){return hasTable;};
    void ResetTable(bool b){ hasTable = b;};
    
};

//派生类RatePlayer写在一齐方便,也可以写在另一个文件  公有基类 TablePlayer
class RatePlayer : public TablePlayer{
    
    
    
};



#endif /* TablePlayer_hpp */


TablePlayer.cpp

TablePlayer::TablePlayer(const string &fn, const string &ln,bool bl):firstName(fn) ,lastName(ln),  hasTable(bl)
{
    
}


void TablePlayer::Name()
{
    
    cout << lastName << "," << firstName << endl;
    
}


RatePlayer.hpp

#ifndef RatePlayer_hpp
#define RatePlayer_hpp

#include <stdio.h>
#include <iostream>
#include <string>
#include "TablePlayer.hpp"

//派生类RatePlayer  公有基类 TablePlayer
class RatePlayer2 : public TablePlayer {

private:
    unsigned int rating;
    
public:
    //派生类需要有自己的构造函数
    RatePlayer2(unsigned int i = 0 , const string & fn = "fn" ,const string & ln = "ln",bool b = false);
    RatePlayer2(unsigned int i , const TablePlayer &t);
    
    unsigned int Rating(){return rating;};
    void ResetRateing(unsigned int i){rating = i;};
    
    
};


#endif /* RatePlayer_hpp */


RatePlayer.cpp

//利用成员初始化列表语法,在派生类创建前对基类初始化
RatePlayer2::RatePlayer2(unsigned int i , const string & fn ,const string & ln ,bool b):TablePlayer(fn,ln,b)
{
    
    rating = i;
}


RatePlayer2::RatePlayer2(unsigned int i , const TablePlayer &t):TablePlayer(t),rating(i)
{
    
    
}


main

#include <iostream>
#include "TablePlayer.hpp"
#include "RatePlayer.hpp"

int main(int argc, const char * argv[]) {

    //基类
    TablePlayer t1("1","111",true);
    TablePlayer t2;
    
    t1.Name();
    if (t1.HasTable())
    {
        cout << "has table\n";
    }
    else
    {
        cout << "has not table\n";
    }
    
    t2.Name();
    if (t2.HasTable())
    {
        cout << "has table\n";
    }
    else
    {
        cout << "has not talbe\n";
    }
    
    
    //派生类,直接调用基类方法
    RatePlayer2 r;
    r.Name();
    r.ResetTable(false);
    
    
    
    //基类指针指向派生类对象
    TablePlayer *t3 = &r;
    
    
    //基类引用派生类对象
    TablePlayer &t4 = r;
    
    
    //派生类直接赋值给基类,
    TablePlayer t5(r);
    
    RatePlayer2 r2(100,"r2","rr",true);
    t5 = r2;

    
    return 0;
}


//多态继承 虚函数

1.在派生类中重新定义基类的方法

2.使用虚方法

注意: *构造函数不可以是虚函数

                 *析构函数应该设置为虚函数,这样当派生类过期时会先调用派生类的析构函数,否则将直接调用基类的析构函数释放派生类的基类中内存部分,而不释放派生类新成员内存

 *友元不能是析构函数,友元不是类成员,只有成员才能是虚函数,也可以通过友元函数使用虚成员函数来解决




class Bass {
    
private:
    int i;
    double f;
    
public:
    
    Bass(const int bi = 10, const double bf = 33.34f):i(bi),f(bf){};
    
    virtual void Check(){ cout << "Base::Check" << endl; };
    virtual ~Bass(){};
    
};




class BassSub:public Bass {

private:
    int t;
    double k;
    
public:
    
    BassSub(const int bi = 10, const double bf = 33.34f):t(bi),k(bf){};
    virtual void Check(){ cout << "BaseSub::Check" << endl; };
    virtual ~BassSub(){};
    
};
//虚函数
    Bass b(10,333.34f);
    BassSub sb(2223,112.5f);
    
    b.Check();  //Base::Check
    sb.Check(); //BaseSub::Check



//私有继承

私有继承的派生类只能在内部调用基类的公有函数,私有继承初始化后外部不能调用基类公有函数

class Test {
private:
    string name;
    valarray<double> source;
public:
    

    void come()
    {
        cout << "private" << endl;
    }
    
    
    
protected:
    
};

class tt : private Test {
    
public:
    
    void doCome()
    {
        this->come();
    }

};

main

//私有继承
    tt t;
    t.doCome();


//保护继承

基类的公有成员函数在保护继承的派生类 变成了保护成员函数




//多重继承

class BaseFirst {
    int bb;

    
public:
    
    int bf;
    
};


class BaseSec {
    
    
public:
    int bs;
};


class Derived : public BaseFirst , public BaseSec {
    
    
public:
    
    int d;

};

//多重继承
    Derived derived;
    derived.bf = 10;
    derived.bs = 20;
    derived.d = derived.bf+derived.bs;



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值