C++7.16

继承:

/*以下的使用区域分别是1、在main函数创建对象调用的时候例如 son. s;s.say(),和 2void son::show(){say()};这两种情况

public继承:在基类中如果参数是

public格式:那么在派生类中,则是public类型,在创建的对象和调用的函数中都可以访问;

private 格式:那么在派生类中,则也是private类型,在创建的对象和调用函数中都不可以访问;

protected 格式:那么在派生类中,在创建的对象不可以访问,调用函数可以访问;

private继承:在基类中如果参数是

public 格式:在派生类中,创建的对象无法直接访问,在类函数中可以访问;

private 格式:那么在派生类中,也是private类型,在创建的对象和调用函数中都不可以访问;

protected 格式:在派生类中,在创建的对象不可以访问,类函数中可以访问;

protected继承:在基类中如果参数是

public 格式: 在派生中,创建的对象无法直接访问,在类函数中可以访问;

private 格式:在派生中,创建的对象和类函数中都不可以访问;

protected 格式:在派生中,在创建的对象中无法访问,在类函数可以访问;

 

总结:    public   private  protected

 

public继承 对象Y函数Y 对象N函数N 对象N函数Y

 

private继承 对象N函数Y 对象N函数N 对象N函数Y

 

protected继承 对象N函数Y 对象N函数N 对象N函数Y

#include <iostream>

 

using namespace std;

 

class A{

protected:

    int score;

public:

    void setscore(int );

};

void A::setscore(int s)

{

    score=s;

}

class B:private A{

private:

    int id;

public:

    void setid(int );

    void getid();

    void getscore();

};

 

void B::setid(int i)

{

    id=i;

}

void B::getid()

{

    cout<<id<<endl;

    setscore(87);

}

void B::getscore(){cout<<score<<endl;}

 

int main()

{

    B b;

    b.score=98;

    b.setscore(98);

    b.setid(1);

    b.getid();

    b.getscore();

}

 

函数遮蔽:

函数遮蔽是指,例如在基类中

class A{

public:

void show();

};

在派生类中:

class B:public A{

public:

void show(int a);

};

在基类和派生类中都有一个函数show()函数 虽然在基类中,show()并没有参数,而在派生类中有int参数,但是还是遮蔽,在main函数中:

int main()

{

B b;

b.show();

从函数的重载定义的话 这边应该是调用 基类函数中,但是因为遮蔽这边调用的是派生类中,

这段代码虽然编译是出错的 因为函数不匹配,出错的会告诉我们备用的函数是void show(int a);说明编译器无法跟踪到 上面一个函数;

****当然如果一个函数中 有两个函数名一样的话 那就不是遮蔽了,是重载,编译器会根据你给的参数匹配函数。

 

 

继承的内存区域:

基类的内存大小取决于其,定义的参数的长度:

 例如:

class A{

private

char a;

int b;

public:

void show();

};

这个基类的长度就是 8;代码存在代码段。

在派生类中:

class B:public A{

int a;

};

派生类的长度是12;不仅包含了自身的长度 还继承了他基类的长度;

 

构造函数的使用:

当在派生函数中使用,基类函数的构造函数的时候,必须在参数列表中调用,因为派生类无法继承基类的构造函数,具体的使用代码如下;

class A{

private

char a;

int b;

public:

A(char ,int);

void show();

};

class B:public A{

private:

int d;

public:

B:

};

B:B(char a,int b,int c):A(a,b ),d(c){}

**1、此外需要强调的是,在参数列表中,是调用A这个函数 所以这里的a,b是实参,不需要带上类型,跟正常的函数调用是一样的。

2、当有多层派生关系的时候,要层层递进,例如A->B,C->D,使用构造函数时,DBC进行调用构造函数,B C再对A进行参数调用,这又会有一个B C谁初始化成功的问题,按出现的顺序来,谁最后初始化就是那个参数赋值成功;

3、析构函数的顺序跟,构造函数是相反的比如书,A->B->C 那么析构的顺序就是C->B->A

多继承的情况下:构造函数执行的顺序跟,定义的顺序是一样的。析构的顺序是相反的:

 

例如:

class C:pubic B,pubic A,pubic C

这里构造的顺序就是B->A->C 析构的顺序 就是C->A->B

 

 

虚继承与虚基类:

在派生类中因为,可能会友菱形派生方式,A->B,C->D;

按照派生的内存分配,在B,C中都有A的参数 比如说A中有一个a

那么在B,C中都有a,D中如果你去调用这个a 那么编译器就会报出一个错误,无法确认这个a是哪个里面的,可能是B也可能是C,由此 引出概念,虚继承,在继承的前面加上virtual修饰,那么就表示这两个,类愿意共享这个a就不会出现,歧义的情况;

代码如下:

#include <iostream>

using namespace std;

class A{

protected:

    int m_a;

public:

    A(int a);

};

A::A(int a):m_a(a){}

class B:public A{

protected:

    int m_b;

public:

    B(int ,int)

};

B::B(int a,int b):A(a),m_b(b){}

class C: public A{

protected:

    int m_c;

public:

    C(int ,int)

};

C::C(int a,int c):A(a),m_c(c){}

class D:public C,public B{

public:

    D(int,int,int,int);

    void say();

private:

    int m_d;

**在这里用构造函数的时候 跟普通的继承有很大的区别,在普通的继承中,D需要调用B C的构造函数,然后B C 再分别调用A的构造函数,但是在这里,D直接调用A的构造函数,而且B C构造函数还是要对A进行构造,但是不起作用。

这就叫做构造函数是受间接基类影响,不是直接基类;

例如A ->B,C->D  AD的间接基类。

 

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值