C++为什么基类指针不能指向继承方式为protected与private的派生类对象?

2025-03-10 01:21:36
推荐回答(2个)
回答1:

  1. public继承方式下

[cpp] view plaincopy

#include   

using namespace std;  

class Animal  

{  

public:  

    Animal(){}  

    void eat()  

    {  

        cout << "eat/n";  

    }  

protected:  

    void play()  

    {  

        cout << "play/n";  

    }  

private:  

    void drink()  

    {  

        cout << "drink/n";  

    }  

};  

class Giraffe: public Animal  

{  

public:  

    Giraffe(){}  

    void StrechNeck()  

    {  

        cout << "Strech neck /n";  

    }  

    void take()  

    {  

        eat();      // ok,公有继承下,基类的公有成员对派生类可见  

//      drink();    // error,公有继承下,基类的私有成员对派生类不可见,也就是说,派生类不能访问基类私有成员  

        play();     // ok,公有继承下,基类的保护成员对派生类可见  

    }  

};  

  

  

int main()  

{  

    Giraffe gir;  

    // 以下三条语句说明基类成员对派生类对象的可见性  

    gir.eat();              // ok,公有继承下,基类的公有成员对派生类对象可见  

    // gir.play();                  // error,公有继承下,基类的保护成员对派生类对象不可见  

    // gir.drink();                     // error,公有继承下,基类的私有成员对派生类对象不可见  

      

    // 下面一条语句说明基类成员对派生类的可见性  

    // 派生类(即对派生类的成员函数,派生类的友元函数和有元类可见性,和派生类对象无关)  

    gir.take();   

      

    gir.StrechNeck();  

    return 0;  

}  


2.private继承方式下

[cpp] view plaincopy

#include   

using namespace std;  

class Animal  

{  

public:  

    Animal(){}  

    void eat()  

    {  

        cout << "eat/n";  

    }  

protected:  

    void play()  

    {  

        cout << "play/n";  

    }  

private:  

    void drink()  

    {  

        cout << "drink/n";  

    }  

};  

class Giraffe: private Animal  

{  

public:  

    Giraffe(){}  

    void StrechNeck()  

    {  

        cout << "Strech neck /n";  

    }  

    void take()  

    {  

        eat();      // ok,私有继承下,基类的公有成员对派生类可见  

//      drink();    // error,私有继承下,基类的私有成员对派生类不可见,也就是说,派生类不能访问基类私有成员  

        play();     // ok,私有继承下,基类的保护成员对派生类可见  

    }  

};  

  

  

int main()  

{  

    Giraffe gir;  

    // 以下三条语句说明基类成员对派生类对象的可见性  

//  gir.eat();          // error,私有继承下,基类的公有成员对派生类对象不可见  

//  gir.play();         // error,私有继承下,基类的保护成员对派生类对象不可见  

//  gir.drink();                // error,私有继承下,基类的私有成员对派生类对象不可见  

  

    // 下面一条语句说明基类成员对派生类的可见性  

    // 派生类(即对派生类的成员函数,派生类的友元函数和有元类可见性,和派生类对象无关)  

    gir.take();   

  

    gir.StrechNeck();  

    return 0;  

}  


3.protected继承方式下

[cpp] view plaincopy

#include   

using namespace std;  

class Animal  

{  

public:  

    Animal(){}  

    void eat()  

    {  

        cout << "eat/n";  

    }  

protected:  

    void play()  

    {  

        cout << "play/n";  

    }  

private:  

    void drink()  

    {  

        cout << "drink/n";  

    }  

};  

class Giraffe: protected Animal  

{  

public:  

    Giraffe(){}  

    void StrechNeck()  

    {  

        cout << "Strech neck /n";  

    }  

    void take()  

    {  

        eat();      // ok,保护继承下,基类的公有成员对派生类可见  

//      drink();    // error,保护继承下,基类的私有成员对派生类不可见,也就是说,派生类不能访问基类私有成员  

        play();     // ok,保护继承下,基类的保护成员对派生类可见  

    }  

};  

  

  

int main()  

{  

    Giraffe gir;  

    // 以下三条语句说明基类成员对派生类对象的可见性  

    //  gir.eat();          // error,保护继承下,基类的公有成员对派生类对象不可见  

    //  gir.play();         // error,保护继承下,基类的保护成员对派生类对象不可见  

    //  gir.drink();        // error,保护继承下,基类的私有成员对派生类对象不可见  

      

    // 下面一条语句说明基类成员对派生类的可见性  

    // 派生类(即对派生类的成员函数,派生类的友元函数和有元类可见性,和派生类对象无关)  

    gir.take();   

      

    gir.StrechNeck();  

    return 0;  

}  

派生类对象可以使用基类的方法,条件是方法在基类中没有被声明为私有的。基类指针可以在不进行显式类型转换的情况下指向派生类对象,基类引用可以在不进行显式类型转换的情况下引用派生类对象。不过,基类指针或引用只能用于调用基类方法,不能调用派生类的方法。通常C++要求引用和指针类型与赋给的类型匹配,但这一规则对继承来说是个例外。不过这种例外只是单向的,不可以将基类对象和地址赋给派生类引用和指针。

回答2:

对于继承方式为protected和private的派生类对象,基类的公有成员、私有成员和保护成员都是不可见的,除非你在派生类中override了基类的成员并声明为public,所以你把基类指针指向protected和private继承的派生类对象时,对于基类的公有成员,这个对象到底能不能访问到呢?他是基类指针,若是基类对象就该能访问,但指向的是这两种方式继承的对象,按理又不能访问,矛盾了,所以不允许他指向这样的对象。(同是小白,个人理解)