08_c++访问控制和继承

来源:互联网 发布:淘宝邮箱注册页面 编辑:程序博客网 时间:2024/05/16 07:09

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;}
原创粉丝点击