08_c++访问控制和继承

c++访问控制和继承

通常认为一个类有2种不同的用户:普通用户类的实现者。普通用户编写的代码使用类的对象,这部分代码只能访问类的公有成员;实现者则负责写类的成员和友元代码,成员和友元既能访问类的公有部分,也能访问类的私有部分。如果进一步考虑继承的话就会出现第3种用户,即派生类。派生类可以访问基类的公有(public)成员和受保护(protected)成员,但不能访问基类的私有(private)成员。

1、派生类不能访问基类的私有(private)成员

class Father {
private:
    int money;
public:
    void it_skill(void)
    {
        cout<<"father's it skill"<<endl;
    }

    int getMoney(void)
    {
        return money;
    }

    void setMoney(int money)
    {
        this->money = money;
    }
};

class Son : public Father {
private:
    int toy;
public:
    void play_game(void)
    {
        int m;

        cout<<"son paly game"<<endl;

        /* money -= 1; 
         * 错: 派生类不能访问基类的私有(private)成员
         */
        m = getMoney();
        m--;
        setMoney(m);
    }
};


int main(int argc, char **argv)
{
    Son s;

    s.setMoney(10);
    cout << s.getMoney()<<endl;

    s.it_skill();
    s.play_game();

    return 0;
}

2、派生类可以访问基类的保护成员,类的对象则不行

class Father {
private:
    int money;

protected:
    int room_key;

public:
    void it_skill(void)
    {
        cout<<"father's it skill"<<endl;
    }

    int getMoney(void)
    {
        return money;
    }

    void setMoney(int money)
    {
        this->money = money;
    }
};

class Son : public Father {
private:
    int toy;
public:
    void play_game(void)
    {
        int m;

        cout<<"son paly game"<<endl;

        /* money -= 1; 
         * 错: 派生类不能访问基类的私有(private)成员
         */
        m = getMoney();
        m--;
        setMoney(m);
        room_key = 1; /* 派生类可以访问基类的保护成员 */
    }
};

int main(int argc, char **argv)
{
    Son s;

    s.setMoney(10);
    cout << s.getMoney()<<endl;

    s.it_skill();
    s.play_game();

    //s.room_key = 1; 类的对象不能访问保护成员

    return 0;
}

3、派生类可以修改基类的权限

派生类可以修改基类的权限,前提是派生类可以访问到基类的成员,即派生类不能修改基类的private成员,因为派生类不能访问基类的private成员。

class Son : public Father {
private:
    int toy;
public:
    using Father::room_key;/* 派生类修改基类成员的权限为public,类的对象可以访问 */
    //using Father::money;/* 派生类不能修改基类的private成员,因为派生类不能访问基类的private成员 */

    void play_game(void)
    {
        int m;

        cout<<"son paly game"<<endl;

        /* money -= 1; 
         * 错: 派生类不能访问基类的private成员
         */
        m = getMoney();
        m--;
        setMoney(m);

        room_key = 1; 
    }
};


int main(int argc, char **argv)
{
    Son s;

    s.setMoney(10);
    cout << s.getMoney()<<endl;

    s.it_skill();
    s.play_game();

    s.room_key = 1; /* 由于派生类将基类的protected成员改为public权限,故可以访问 */  
    return 0;
}

4、private,protected,public继承的区别

无论是哪种继承方式,在派生类内部使用父类时并无差别,即无论什么方式继承,派生类可以访问基类的protected和public成员。不同的继承方式,会影响这两方面:外部代码对派生类的使用派生类的子类

class Father {
private:
    int money;

protected:
    int room_key;

public:
    int address;

    void it_skill(void)
    {
        cout<<"father's it skill"<<endl;
    }
};

class Son_pub : public Father {
private:
    int toy;
public:

    void play_game(void)
    {
        room_key = 1; // **无论是哪种继承方式,在派生类内部使用父类时并无差别**
    }
};


class Son_pro : protected Father {
private:
    int toy;
public:

    void play_game(void)
    {
        room_key = 1; // **无论是哪种继承方式,在派生类内部使用父类时并无差别**
    }
};


class Son_pri : private Father {
private:
    int toy;
public:

    void play_game(void)
    {
        room_key = 1; // **无论是哪种继承方式,在派生类内部使用父类时并无差别**
    }
};


int main(int argc, char **argv)
{
    Son_pub s_pub;
    Son_pro s_pro;
    Son_pri s_pri;

    s_pub.play_game();
    s_pro.play_game();
    s_pri.play_game();


    s_pub.it_skill();
    //s_pro.it_skill();  // 错误,protected继承,使用则不能访问protected成员
    //s_pri.it_skill();  // 错误,private继承,使用则不能访问private成员

    return 0;
}

5、覆写

派生类实现基类相同的函数,在使用时会调用派生类的函数,不会调用基类的函数。

class Father {
private:
    int money;

protected:
    int room_key;

public:
    void it_skill(void)
    {
        cout<<"father's it skill"<<endl;
    }
};

class Son : public Father {
private:
    int toy;
public:
    using Father::room_key;
    /* 覆写 override */
    void it_skill(void)
    {
        cout<<"son's it skill"<<endl;
    }

};


int main(int argc, char **argv)
{
    Son s;
    s.it_skill();//调用派生类的it_skill
    return 0;
}

6、派生类到基类的类型转换

一个派生类的对象中,包含继承自基类的部分和派生类自定义的部分。正因为派生类含有基类部分,所以可以进行派生类到基类的类型转换,这种转换是隐式的。不存在从基类向派生类的隐式类型转换。
派生类向基类的自动类型转换只对指针或引用有效,对象之间不存在类型转换。

class Person {
private:
    char *name;
    int age;
public:
    void printInfo(void)
    {
        cout<<"father's printInfo"<<endl;
    }
};


class Student : public Person {
private:
    int grade;
public:
    void printInfo(void)
    {
        cout<<"Student ";
        Person::printInfo();
    }
};

void test_func(Person &p)//传入的参数为基类的引用
{
    p.printInfo();
}

int main(int argc, char **argv)
{
    Person p;
    Student s;

    test_func(p);
    test_func(s); /* Person &p = s里面的Person部分; 发生隐式转换
                   * p引用的是"s里面的Person部分"
                   */
    s.printInfo();
    return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值