c++--面向对象特性

1.面向对象指的是继承,封装,多态。
继承主要关注类的构造,赋值,析构。
以下对多态,封装进行补充说明。

2、多态
2.1.定义
a.赋值
派生类的指针,可以赋值给基类的指针。
派生类的对象,可以赋值给基类的引用。
b.调用
通过基类指针调用基类虚函数时,若派生类提供了派生实现,则调用派生类版本。
通过基类引用调用基类虚函数时,若派送类提供了派送实现,则调用派生类版本。

2.2.最佳实践
基类的析构函数应该定义成虚函数。

#include <iostream>

class Base
{
public:
    Base() {
        fun();
    }
    virtual void fun()
    {
        printf("B_fun()\n");
    }

    void fun1()
    {
        printf("B_fun1()\n");
        fun();
    }

    virtual ~Base()
    {
        printf("~Base()\n");
    }

protected:
    int m_pro;

private:
    int m_pri;
};

class A : public Base
{
public:
    A() : Base() {}

    void fun()
    {
        printf("A_fun()\n");
    }

    ~A()
    {
        printf("~A()\n");
    }
};

int main()
{
    A *pA = new A();
    Base *pB = pA;
    pB->fun1();
    delete pB;

    A a;
    Base &b = a;
    b.fun1();
    return 0;
}

在这里插入图片描述
2.3. 注意点
多态针对类外部使用基类指针或基类引用调用基类虚函数时会发生。
多态针对基类内部调用虚函数,在隐式的this此时关联到派生实例时也会发生。
值得注意的是:在基类的构造函数中,this永远都关联到基类自身.只有在基类的非构造函数中,this才有可能被关联到派生类实例并引发多态访问.

#include <iostream>

class Base
{
public:
    Base() {}
    virtual void fun()
    {
        printf("B_fun()\n");
    }

    void fun1()
    {
        printf("B_fun1()\n");
        fun();
    }

    virtual ~Base()
    {
        printf("~Base()\n");
    }

protected:
    int m_pro;

private:
    int m_pri;
};

class A : public Base
{
public:
    A() : Base() {}

    void fun()
    {
        printf("A_fun()\n");
    }

    ~A()
    {
        printf("~A()\n");
    }
};

int main()
{
    A *pA = new A();
    Base *pB = pA;
    pB->fun1();
    delete pB;

    A a;
    Base &b = a;
    b.fun1();
    return 0;
}

在这里插入图片描述
3.封装
3.1. 访问权限修饰符
a. c++支持的访问权限修饰符有public,protect,private
b. 在类型内部,针对类型自身所有成员(不含基类)具有全量(public,protect,private)访问权限。
c. 在类型内部,针对类型基类,只能访问基类的public,protect修饰的成员。
c. 在类型友元内部,具有等价于类型内部的访问权限。故对类型自身成员有全量访问权限,只能访问基类的public,protect修饰的成员。
d. 在类型外部,针对类型自身成员,只对public成员具备访问权限。针对基类成员,只对public继承的基类的public成员具备访问权限。

#include <iostream>

class Base
{
    // 类的友元--全量访问
    friend void friend_fun();
public:
    Base(int i, int j, int k) : m_pub(i), m_pro(j), m_pri(k) {}
    void fun()
    {
        // 类内部访问--全量访问
        printf("pub_%d,pro_%d,pri_%d\n", m_pub, m_pro, m_pri);
    }

public:
    int m_pub;
protected:
    int m_pro;
private:
    int m_pri;
};

class A1 : public Base
{
    friend void friend_funA1();

public:
    A1(int i, int j, int k) : Base(i, j, k) {}
    void fun1()
    {
        // 公共继承者的内部--只能访问公共基类的public&protect
        printf("pub_%d,pro_%d,pri_%d\n", m_pub, m_pro, 0);
    }
};

// 保护继承
class A2 : protected Base
{
    friend void friend_funA2();
public:
    A2(int i, int j, int k) : Base(i, j, k) {}
    void fun1()
    {
        // 保护继承者的内部--只能访问保护基类的public&protect
        printf("pub_%d,pro_%d,pri_%d\n", m_pub, m_pro, 0);
    }
};

// 私有继承
class A3 : private Base
{
    friend void friend_funA3();

public:
    A3(int i, int j, int k) : Base(i, j, k) {}
    void fun1()
    {
        // 私有继承者的内部--只能访问私有基类的public&protect
        printf("pub_%d,pro_%d,pri_%d\n", m_pub, m_pro, 0);
    }
};

void friend_fun()
{
    // 友元的内部--对类型自身成员全量访问
    Base b(1, 2, 3);
    printf("pub_%d,pro_%d,pri_%d\n", b.m_pub, b.m_pro, b.m_pri);
}

void friend_funA1()
{
    // 友元的内部--对基类,公共基类的public&protect
    A1 b(1, 2, 3);
    printf("pub_%d,pro_%d,pri_%d\n", b.m_pub, b.m_pro);
}

void friend_funA2()
{
    // 友元的内部--对基类,保护基类的public&protect
    A2 b(1, 2, 3);
    printf("pub_%d,pro_%d,pri_%d\n", b.m_pub, b.m_pro);
}

void friend_funA3()
{
    // 友元的内部----对基类,私有基类的public&protect
    A3 b(1, 2, 3);
    printf("pub_%d,pro_%d,pri_%d\n", b.m_pub, b.m_pro, 0);
}

int main()
{
    Base b(11, 22, 33);
    // 类不相干的外部--针对类自身成员,只能访问类自身的public成员。
    b.m_pub;

    A1 a1(2, 3, 4);
    // 类不相干的外部--针对类基类成员,只能访问公共基类自身的public成员。
    printf("pub_%d,pro_%d,pri_%d\n", a1.m_pub, 0, 0);
     // 类不相干的外部--针对类基类成员,只能访问公共基类自身的public成员。
    A2 a2(3, 4, 5);
    printf("pub_%d,pro_%d,pri_%d\n", 0, 0, 0);
     // 类不相干的外部--针对类基类成员,只能访问公共基类自身的public成员。
    A3 a3(4, 5, 6);
    printf("pub_%d,pro_%d,pri_%d\n", 0, 0, 0);
}

理解继承时,对基类的权限修饰。可以认为是指定基类成员被合并到派生类成员时,允许放入的权限区域。
public继承,允许被放入public,protect,private区域。所以,按基类成员一致权限放入。
protect继承,允许被放入protect,private区域。所以,基类public,protect成员放入protect区域;private成员放入private区域。
private继承,允许被放入private区域。所以,基类成员一致放入private区域。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

raindayinrain

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值