C++ 派生类无法访问私有成员
在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
这个概念是派生类对象,成员函数不能访问父类的私有成员。但是,如果父类的公共成员函数返回私有变量的引用,并且父类在子类中被公开继承,并且子类有一个函数(在本例中为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的关注点是