通过指向派生类的指针访问派生成员变量
Posted
技术标签:
【中文标题】通过指向派生类的指针访问派生成员变量【英文标题】:accessing derived member variables via pointers to derived class 【发布时间】:2015-10-12 17:08:11 【问题描述】:我试图理解访问派生对象成员背后的逻辑。我有两个指针:如果我通过指向派生类的指针更改派生类中的变量,我注意到我无法通过指向基类的指针的继承类型访问变量的值。
#include <iostream>
#include <string>
class A
public:
int x;
;
class B : public A
public:
int y;
;
int main()
B* pB = new B;
A* pA = new B;
std::cout<<"Changing x via pB to 11"<<std::endl;
pB->x=11;
std::cout<<"This is x: " << pB->x<<std::endl;
std::cout<<"What about this x: " << pA->x<<std::endl<<std::endl;
std::cout<<"Changing x via pA to 42"<<std::endl;
pA->x=42;
std::cout<<"This is my new x: " << pB->x<<std::endl;
std::cout<<"and what about this x now: " << pA->x;
delete pA;
delete pB;
输出:
通过 pB 将 x 更改为 11 这是 x:11 这个 x 怎么样:0
通过 pA 将 x 更改为 42 这是我的新 x:11 那么这个 x 现在呢:42
我想知道发生了什么以及为什么 x 有两个不同的值。让我感到困扰的是,例如,当我使用多个列表工作时:一个主列表,其中包含指向我所有对象(比如某个动物类)的指针和一个辅助列表——主列表的子样本,其中包含指向某些对象的指针对象(比如爬虫类:公共动物,公共捕食者)——碰巧我希望通过第二个列表(布尔 is_currently_in_water)修改这些成员的值,我不能以一种直接(而且对我来说很直观)的方式做到这一点.我必须跟踪主列表并首先找出哪个动物对象是爬行动物,以便通过主列表进行必要的更改。
多态性是这样设计的吗?这可能是一个非常基本的问题,因为我刚开始学习 C++,虽然我知道如何克服更改代码的问题,但我首先尝试完全掌握发生了什么,因为上述结果相当令人惊讶。
【问题讨论】:
【参考方案1】:我想知道发生了什么以及为什么
x
有两个不同的值。
解释很简单:你有两个x
值,因为你有两个B
类型的独立对象,通过两个指针pA
和pB
引用,它们完全相互独立。
当您打印pB->x
时,您将打印x
附加到您首先分配的对象;当您打印pA-X
时,您会打印附加到您第二次分配的对象的x
。这两个对象不共享成员变量,所以它们的x
s 是相互独立的。
如果您想查看两个不同类型的指针指向同一个对象时的行为,请执行以下操作:
B* pB = new B;
A* pA = pB;
现在pA
和pB
指向同一个对象,因此通过一个指针对x
的任何更改都将通过另一个指针“可见”。当然,现在只有一个分配,您需要删除delete pA
(或delete pB
,如果您愿意)以避免重复删除同一个对象。
【讨论】:
就是这样!这就是我想要的!非常感谢..我多么愚蠢!我没有注意到我的错误并且我的程序运行良好,直到突然我在查询奇怪的行为!既然你直觉地知道我想要做什么,我会给你投票(尽管你第二个回答).... :-) 顺便说一句。如何使用 shared_ptr 做到这一点?在这里收到奇怪的错误消息。 @user2856452 这是一个非常有趣的问题,SO 有几个很好的答案(1 和 2)。【参考方案2】:有 2 个不同的值,因为您有 2 个不同的对象:
B* pB = new B;
A* pA = new B;
pA
指向的对象与pB
指向的对象没有任何关系。而且,在第一个
std::cout<<"What about this x: " << pA->x<<std::endl<<std::endl;
您正在读取未初始化的数据,这是未定义的行为。
【讨论】:
这是有道理的。谢谢!我实际上想创建两个指向同一个对象的指针(但指的是不同的基类)这可能吗?【参考方案3】:您试图从两个不同的对象中读取 x。
如果你想用父指针引用你的对象,你需要定义一个父指针,如下所示
B* pB = new B;
A* pA = pB;
现在如果你从指针 pA 改变 x,它也会在 pB 上改变。
【讨论】:
以上是关于通过指向派生类的指针访问派生成员变量的主要内容,如果未能解决你的问题,请参考以下文章