search

Home  >  Q&A  >  body text

c++ 公有继承中,私有成员只能通过基类接口访问,如果我把派生类强制转换为基类,是否能访问其基类私有成员

而我的代码是印发错误的,为什么?

///////////////// .h
#ifndef HI_H_INCLUDED
#define HI_H_INCLUDED
#include <iostream>
using namespace std;
class Worker
{
    string name;

public:
    Worker(string na):name(na){}
private:    
    void data()
    {
        cout<<"worker"<<endl;
    }

};
class Waiter:virtual public Worker
{

public:
    Waiter(string na1):Worker(na1){}


    void show()
    {
        ((Worker &)*this).data();   ///强制转化为基类,为什么还是不能调用私有函数data()
        data();
    }
private:
    void data()
    {
        cout<<"waiter"<<endl;
    }
};


#endif // HI_H_INCLUDED

////////////  .cpp
#include <iostream>
#include "hi.h"
#include<stdlib.h>

using namespace std;


int main()
{
    Worker a("lin");
    Waiter b("liu");

    b.show();
    system("pause");
}
ringa_leeringa_lee2809 days ago824

reply all(2)I'll reply

  • PHPz

    PHPz2017-04-17 15:38:02

    Of course this is not possible.

    The purpose of declaring a member as private is to prevent you from using it in subclasses. If it can be used after forced type conversion like the subject, what is the purpose of privatethis access specifier? Only public and protected It would be nice if it wasn’t.

    If you want to overload the function of the parent class, you can modify two lines:

    class Worker
    {
        string name;
    
    public:
        Worker(string na):name(na){}
    //private:
    protected:  // <-- 1
        void data()
        {
            cout<<"worker"<<endl;
        }
    
    };
    class Waiter:virtual public Worker
    {
    
    public:
        Waiter(string na1):Worker(na1){}
    
    
        void show()
        {
            //((Worker &)*this).data();   ///强制转化为基类,为什么还是不能调用私有函数data()
            Worker::data(); // <-- 2 调用父类的同名方法
            data();  // <-- 3 此处会调用子类的方法
        }
    private:
        void data()
        {
            cout<<"waiter"<<endl;
        }
    };

    reply
    0
  • 黄舟

    黄舟2017-04-17 15:38:02

    If the base class is not very complicated, there is still a way to do it.
    Declare a structure or class that is almost the same as the base class. If it is a class, declare all permissions as public, and then cast the original object pointer into the new class you declared.
    The new structure implements the following points:
    1. You need to declare the member variables from the first to the one you need to access in the original base class. For example, there are 5 variables in the original base class, and the third one you need to access is the first 3 variables in the structure. If the original base class has other base classes, the structure will also be derived from them. That’s it
    3. If there is a virtual function in the base class, add a destructor with virtual to the structure.
    4. The alignment should be the same as the base class
    Follow this method and basically everything will be done
    Don’t say anything that undermines encapsulation. The original fault lies in the lack of thoughtful consideration by the designer of the base class

    reply
    0
  • Cancelreply