我对C 的经验不是,而是尝试学习。
以下示例由"相关"类的层次结构组成:
- 儿童是 parent1 和 parent2 的孩子
- parent2 是 VirtualGrandParent 的孩子。
- parent2 包含成员姐妹* m_sister ,它是另一个用户定义对象类型的指针。这是Parent2构造函数中的关键字 new 的初始化和分配的内存。在执行中的某个时刻,此指针设置为0。
mainclass.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;
};
姐妹:
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 :如果将地址在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* ptr
施放到Parent1
时,您无法正确地铸造或下层次结构。相反
对于沿继承层次结构施放,请尝试始终使用至少static_cast
(如果需要的话,或dynamic_cast
)。使用static_cast
,编译器将验证铸件至少可能是可能的,否则会出现错误。在您的情况下,应该显示错误。
适当的演员将是static_cast<Parent1*>(static_cast<Child*>(ptr))
至于您关于&ptr
的第二个问题...将指针到A分量作为指针到A级的级别简直是胡说八道。如果看起来完全有效,那是不确定的行为的不幸运气。(而且它可能实际上不是正常工作的,而是解释一些任意内存,就好像是您的类一样,然后恰好具有非零的值,而某种程度上是某种程度上的,但在任何方面都不有效。)