我想使用指向具有继承类型的类数据成员的指针。代码非常简单,我有一个带有数据成员的对象(A),其中类(Integer)继承了另一个类(Type),我想使用父类(Type *)创建一个指向这个数据成员的指针而不是基类(整数):
class Type
{
public:
Type() {}
};
class Integer : public Type
{
public:
Integer() : Type() {}
int value;
};
class A
{
public:
A() { p_value.value = 0; };
Integer p_value;
};
int main()
{
Type* aType = &A::p_value;
return 0;
}
我有编译错误:
error line: Type* aType = &A::p_value;
error: cannot convert 'Integer A::*' to 'Type*' in initialization
经过大量摆弄代码后我无法正常工作,我做错了什么?
答案 0 :(得分:2)
基本上指针类型不匹配。 &A::p_value
类型为A::*Integer
(或Integer A::*
,编译器很好地说明了),而Type*
只是...... Type*
。
前(A::*Integer
)是指向成员的指针,可以像这样使用:
A a1;
A* a2 = new A;
A::*Integer a_member = &A::p_value;
a1.*a_member = 1;
a1->*a_member = 2;
// now a.p_value == 1 a->p_value == 2
同时Type*
只是指向Type
对象的指针 - 因为Type
类层次结构与A类层次结构是分开的,所以类之间没有任何转换是有意义的。在这里,您希望从指向成员的指针转换为指向类的指针。你很可能想要这样的事情:
int main()
{
A a;
Type* aType = &a.p_value;
return 0;
}
差异在于他们的所作所为。指向类的指针将在对象的内存开头查找,然后使用有关此对象中特定成员/虚函数指针所在位置的信息,转到那里并返回值。 我们使用它们来获取数据或基于对象的地址调用虚拟方法。
另一方面,指向成员的指针只知道对象的内存开始和搜索数据位置之间的区别。因此,您需要同时拥有对象的地址和增量来确定数据的位置:
(object_by_value).*(pointer_to_member);
(object_by_pointer)->*(pointer_to_member);
通过他们的工作方式,你可以理解,将一个投射到另一个只会产生垃圾,编译器可以通过警告来避免这个错误:
cannot convert 'Integer A::*' to 'Type*' in initialization