第四课 类之间的关系

本文介绍了面向对象中的横向关系,如组合、依赖、关联和聚合,以及纵向关系——继承的概念和特点。详细阐述了继承的基本知识,包括继承顺序、优点、方式和隐藏机制。同时,讨论了函数重载与隐藏的区别,并解析了类成员函数指针在多态中的作用。
摘要由CSDN通过智能技术生成

一、横向关系

1.1 组合

“is part of”相当于人和手的关系

class CHead{};
class CPeople{
    CHead m_head;
};

1.2 依赖

“use a”相当于使用工具,人编程依赖于电脑

class CComputer{};
class CPeople{
    void Code(CComputer m_com){}
};

1.3 关联

“has a”相当于和朋友的关系

class CFriend{};
class CPeople{
    CFriend *p_Fri;
};

1.4 聚合

相当于人和家庭的关系

class CPeople{};
class CFamily{
    CPeople *p_myFamily[10];
};

二、纵向关系(继承)

(一)基本知识

1.继承:子类包含且可以使用父类成员

2.父类和子类可以定义同名成员,使用时默认调用子类成员,使用父类成员时需要显示指定(类名:成员名称)

3.定义子类对象时包含父类成员属性,也在内存中为父类的成员属性开辟内存空间

顺序是先父类后子类

4.父类成员应该在父类的构造函数中进行初始化(自己负责自己的初始化

5继承下执行构造的顺序:父类->子类,析构顺序:子类->父类

(在执行构造的时候,调用子类的构造函数,会先执行初始化参数列表,执行父类的构造;回收子类,肯定先调用子类的析构,之后回收父类对象,调用父类析构)

(二)继承优点

把相似类里面相似的方法放到父类里,子类可以继承使用;只维护父类的代码,无论增加还是修改,只需要写一份代码

增加代码的复用性,扩展性和灵活性

(三)继承方式

继承方式和访问修饰符,共同决定了类内成员的适用范围的控制

3种(public protected private)

有public, protected, private三种继承方式,它们相应地改变了基类成员的访问属性。

public 继承:基类 public 成员,protected成员,private 成员的访问属性在派生类中分别变成:public, protected, private

protected 继承:基类public 成员,protected成员,private 成员的访问属性在派生类中分别变成:protected, protected,private

private继承:基类public成员,protected成员,private成员的访问属性在派生类中分别变成:private, private, private

(四)隐藏

4.1 在同一作用域下,函数名相同,参数列表不同的函数,我们称之为函数重载

在父类和子类中,由于作用域不同,所以相同函数名,不同参数列表的函数,并不是函数重载,而是隐藏,调用父类,需显式指定。

class A{
public:
    void show(int a,int b)//隐藏:子类成员中存在同名
    {
        cout<<"void show(int a,int b)"<<endl;
    }
};

class AA:public A{
public:
    void show(int a){
    cout<<"void show(int a)"<<endl;
    }
}

显式指定

AA aa;
aa.A::show(10,20);

4.2 父类指针可以直接指向子类对象,且不需要进行强转

A *pthis=&aa;//不报错

因此父类的函数的this指针可以指向子类对象,子类对象可以调用父类的非静态成员函数

除此之外可以利用这个特性,统一多种子类类型

提高代码的复用性和扩展性

弊端:父类指针 不能调用子类独有的函数

(五)类成员函数指针

1.函数指针

void show()
{

}

int mian()
{
    
    void (*p_fun1)()=nullptr;
    void (*p_fun2)()=&show;

    *p_fun2();//相当于show()

    
    typedef void (*P_FUN)();
    P_FUN p_fun3=&show;
    (*p_fun3)();

}

函数指针的优点:

函数指针可以指向功能相似的不同模块统一标识,使系统结构清晰,便于后期维护(利于系统的抽象,使用接口实现分离,降低代码的耦合度,提高代码的复用性和扩展性)

void show()
{

}

void GetShow(void (*p_fun)())
{
    //show();
    (*p_fun)();
}

int main()
{
    Getshow(&show);

}

2.类成员函数指针

class CTest{
public:
    void show()
    {

    }

}

int main()
{
    //在C++中,提供一个整体操作::*来定义类成员函数指针
    void (CTest ::* p_fun)=&CTest::show();


    //.*、->* 是整体操作,通多对象调用类成员函数指针指向的类成员
    CTest tst;
    (tst.*p_fun)();

    CTest *pTst=new CTest;
    (pTst->*p_fun)();
    

}

3.类成员函数指针可以解决的问题

通过强转,父类指针可以指向子类中特有的函数 

因此可以实现多态

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值