C++ 派生类无法访问私有成员

C++ 派生类无法访问私有成员,c++,inheritance,reference,C++,Inheritance,Reference,在C++中: 这个概念是派生类对象,成员函数不能访问父类的私有成员。但是,如果父类的公共成员函数返回私有变量的引用,并且父类在子类中被公开继承,并且子类有一个函数(在本例中为display()),该函数从父类(在本例中为show())调用该函数并获取私有变量x的引用,该怎么办。a的地址应该与x匹配,但我不知道为什么它不同 enter code here #include <iostream> using namespace std; class test{ int x=1

在C++中:
这个概念是派生类对象,成员函数不能访问父类的私有成员。但是,如果父类的公共成员函数返回私有变量的引用,并且父类在子类中被公开继承,并且子类有一个函数(在本例中为display()),该函数从父类(在本例中为show())调用该函数并获取私有变量x的引用,该怎么办。a的地址应该与x匹配,但我不知道为什么它不同

enter code here

#include <iostream>

using namespace std;
class test{
    int x=10;
    public:
    int & show();
};
class ChildTest: public test{
    public:
    void display(){
        int a=show();
        cout<<&a<<endl;
    }
};
int & test::show(){
    cout<<&x<<endl; //so this address should match the above address but it //is not matching I don't understand why?
    return x;
}
int main()
{
    ChildTest obj;
    obj.display();
    return 0;
}
在此处输入代码
#包括
使用名称空间std;
课堂测试{
int x=10;
公众:
int&show();
};
班级测试:公共测试{
公众:
无效显示(){
int a=show();

cout在这里,您只需显示局部变量
a的地址(其值为
test::x


更改为
int&a=show();
以显示相同的地址。

这里您只需显示局部变量
a
(其值为
test::x

更改为
int&a=show();
以显示相同的地址。

写入时

int a = show();
您的意思是“创建一个名为
a
的全新整数变量,并使用
show()
的返回值对其进行初始化。即使
show
返回一个
int&
,因为您明确表示“我想要一个新的
int
”,“C++创建一个存储在<代码> int <代码>中的值的副本,该代码返回的代码为< >())/>代码>

若要修复此问题,请将代码更改为

int& a = show();
这表示“创建一个新的
int
引用,并将其绑定到
show()
返回的引用所引用的任何引用。”这样,就不会生成整数的副本,您应该可以看到相同的地址

请注意,这与继承无关。它纯粹是复制
int
的功能,而不是在编写时存储引用。

int a = show();
您的意思是“创建一个名为
a
的全新整数变量,并使用
show()
的返回值对其进行初始化。即使
show
返回一个
int&
,因为您明确表示“我想要一个新的
int
”,“C++创建一个存储在<代码> int <代码>中的值的副本,该代码返回的代码为< >())/>代码>

若要修复此问题,请将代码更改为

int& a = show();
这表示“创建一个新的
int
引用,并将其绑定到
show()
返回的引用所引用的任何引用。”这样,就不会生成整数的副本,您应该可以看到相同的地址


请注意,这与继承无关。它纯粹是复制
int
而不是存储引用的函数。

整数是一个值。例如,如果使用自定义类而不是整数,则会得到相同的地址。但是,作为值类型,所有整数变量在内存中都有各自的空间。若要具有相同的地址,应将变量
a
更改为指向整数值的指针:

    void display() {
        int* a=show();
        cout<<a<<endl;
    }

编辑:有一个错误,当我写这篇文章时,其他人回答了。

整数是一个值。例如,如果您使用自定义类而不是整数,您将获得相同的地址。但是,作为一个值类型,所有整数变量在内存中都有各自的独立空间。要拥有相同的地址,您的变量
a
应该是be更改为指向整数值的指针:

    void display() {
        int* a=show();
        cout<<a<<endl;
    }

编辑:我写这篇文章时出错了,其他人回答了。

如果
show()
不返回引用吗?@Omnifarious Hoo boy,如果你存储了一个非
常量的引用,那么你就有麻烦了,因为你有一个悬空的引用。但是,我想,在这种情况下,OP看到不同的地址不会感到惊讶,因为他们明确选择返回原始值的副本。事实上通常,不,
display()
运行正常,并且保证在
show()
返回
int
(而不是
int&
)的情况下运行正常.现在,如果display试图返回其引用,那么问题就从这里开始。如果您显式创建对临时对象的命名引用,则该临时对象将保证在该名称的生命周期内一直存在。请尝试帮助您改进您的答案。:-@Omnifarious我想我遗漏了一些内容。我认为OP的关注点是添加在
display
中打印的ress与在
show
中打印的地址不匹配。如果
show
按值返回其结果,则
display
将不得不打印出与
show
不匹配的地址,因为它显示的
int
值不同。也许我误解了但是,你暗示的是什么。你对OPs的问题回答得很好。我以为你用了一句关于show的返回值的话,用了一种将引用绑定到返回值的方式。但是重新阅读时我错了。如果
show()
不返回引用吗?@Omnifarious Hoo boy,如果你存储了一个非
常量的引用,那么你就有麻烦了,因为你有一个悬空的引用。但是,我想,在这种情况下,OP看到不同的地址不会感到惊讶,因为他们明确选择返回原始值的副本。事实上通常,不,
display()
运行正常,并且保证在
show()
返回
int
(而不是
int&
)的情况下运行正常.现在,如果display试图返回其引用,那么问题就从这里开始。如果您显式地为临时对象创建命名引用,则该临时对象将保证在该名称的生命周期内一直存在。请尝试帮助您改进您的答案。:-@Omnifarious我想我遗漏了一些内容。我认为OP的关注点是