gpt4 book ai didi

c++ - 在 C++ 中对指针 "sideways"进行类型转换时会发生什么

转载 作者:行者123 更新时间:2023-11-28 02:04:56 25 4
gpt4 key购买 nike

我对 C++ 没有那么多经验,但正在努力学习。

以下示例由“相关”类的层次结构组成:

  • ChildParent1Parent2 的 child
  • Parent2VirtualGrandParent 的 child 。
  • Parent2 包含一个成员 Sister* m_sister,它是指向另一个用户定义对象类型的指针。这是在 Parent2 的构造函数中使用关键字 new 初始化和分配的内存。在执行过程中的某个时刻,此指针设置为 0。

主类.cpp:

#include "WorkerClass.h"
using namespace std;

int main()
{
WorkerClass worker;

worker.initialize();
worker.setProperty1();
worker.setProperty2();
// At this point m_sister (in Parent2) is set to 0x0, which makes the next method call fail (Segmentation fault). What happens?

worker.setAuntValue();

return 0;
}

WorkerClass.h:

#include <map>
#include "Child.h"

class WorkerClass
{
public:
void initialize()
{
Child* child1 = new Child();
m_myMap[0] = child1;
}

void setProperty1()
{
VirtualGrandParent* ptr = m_myMap[0];
((Parent1*) ptr)->setProperty1(6.0);
}

void setProperty2()
{
VirtualGrandParent* ptr = m_myMap[0];
((Parent1*) ptr)->setProperty2(7.0);
}

void setAuntValue()
{
VirtualGrandParent* ptr = m_myMap[0];
((Child*) ptr)->setSisterValue(170.0);
}

private:
map<int, VirtualGrandParent*> m_myMap;
};

child .h

#include "Parent1.h"
#include "Parent2.h"

class Child : public Parent1, public Parent2
{
public:
Child(): Parent1(), Parent2() {}
~Child(){};
};

Parent1.h:

class Parent1
{
public:

Parent1(): m_value1(0.0), m_value2(0.0) {}
virtual ~Parent1() {};

void setProperty1(double val) {m_value1=val;}
void setProperty2(double val) {m_value2=val;}

private:
double m_value1;
double m_value2;
};

Parent2.h:

#include "Sister.h"
#include "VirtualGrandParent.h"

class Parent2 : public VirtualGrandParent
{
public:
Parent2(): VirtualGrandParent() {m_sister = new Sister();}
~Parent2(){};

void setSisterValue(double val){m_sister->setValue(val);}

protected:
Sister* m_sister;
};

姐姐.h:

class Sister {
public:
Sister(): m_sisterVal(0.0) {};

void setValue(double val)
{
m_sisterVal=val;
}
private:
double m_sisterVal;
};

VirtualGrandParent.h:

class VirtualGrandParent
{
public:
VirtualGrandParent() {}
virtual ~VirtualGrandParent(){};
};

问题 1:所以我的主要问题是在从 VirtualGrandParent 到 Parent1 的“横向”转换过程中发生了什么?为什么 m_sister 是 0?内存是否被覆盖?为什么在 m_sister 为 0 之前需要 两次 方法调用?

问题 2:如果将 address 取到 WorkerClass.h 中的 指针 ptr,然后将其转换为 Parent1* 会发生什么指针(下面的例子)?执行带有此更改的代码会导致 m_sister 未设置为 0。我认为这只是巧合? (我想一个指向指针的指针真的应该是 Parent1** 类型?)

void setProperty1()
{
VirtualGrandParent* ptr = m_myMap[0];
((Parent1*) &ptr)->setProperty1(6.0);
}

最佳答案

因此,如果我们将亲子关系视为一棵树:

VirtualGrandParent
\
Parent2 Parent1
\ /
Child

然后我们可以看到Parent1和VirtualGrandParent在不同的分支上。所以当你投 VirtualGrandParent* ptrParent1您没有正确地向上或向下转换层次结构。取而代之的是跨它进行强制转换,最终在不相关的类之间进行强制转换 - 这就是它产生无效结果的原因。

为了沿继承层次结构进行转换,请尝试始终至少使用 static_cast (或 dynamic_cast 如果需要)。用static_cast编译器将验证转换是否至少是可能的,否则会报错。在您的情况下,它应该显示错误。

正确的转换应该是 static_cast<Parent1*>(static_cast<Child*>(ptr))

关于你的第二个问题&ptr ...将指向指针的指针转换为指向类的指针简直是无稽之谈。如果它看起来完全有效,那就是未定义行为的不幸运气。 (而且它可能实际上没有正常工作,而是将一些任意内存解释为好像它是你的类,然后它恰好有一个非零值,而 somePtr 应该是但无论如何都无效。)

关于c++ - 在 C++ 中对指针 "sideways"进行类型转换时会发生什么,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37908185/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com