发布网友 发布时间:2022-04-23 13:32
共4个回答
热心网友 时间:2023-10-15 20:27
C++父类和子类对象指针之间的转换
C++父类和子类对象指针之间的转换,有示例代码
C++父类和子类对象指针之间的转换
由子类向父类转换很简单, 用默认转换.
例如 CWnd* pWnd = (CWnd*)(&ChildView);
由父类向子类, 用dynamic_cast. 使用dynamic_cast是有*的.
例如对如下语句:
CPoint3D* p1 = dynamic_cast(p);
1.p虽然是CPoint类型, 但是p应当实际指向一个CPoint3D对象. 如果p实际指向的不是一个CPoint3D对象,则转换后的返回值为NULL.
2.VC中必须在project setting中设定/GR选项, 即Enable Runtime Type Identification(RTTI).
下面是一段示例代码:
#include <iostream>
using namespace std;
class CPoint
{
public:
virtual void f(){cout << "CPoint::f" <<endl;}
};
class CPoint3D : public CPoint
{
public:
virtual void f(){cout << "CPoint3D::f" <<endl;}
};
int main()
{
CPoint point,*pPoint;
CPoint3D point3D,*pPoint3D;
//子类向父类类型转换,直接强制转换就可以了,但实际仍然指向子类对象
pPoint = (CPoint*)&point3D;
pPoint->f(); //调用的仍然是子类的函数,这便是虚函数的魅力所在
//父类向子类类型转换,要用dynamic_cast
pPoint3D = dynamic_cast(pPoint);
pPoint->f(); //pPoint实际指向一个CPoint3D对象,故可以正确转换
pPoint3D = dynamic_cast(&point);
cout << (int*)pPoint3D << endl; //&point指向的不是一个CPoint3D对象,返回值为NULL
return 0;
}
运行结果为:
CPoint3D::f
CPoint3D::f
00000000
热心网友 时间:2023-10-15 20:27
father类没有任何成员,你能看到什么数据呢?它只是一个空类
将bb转换到父类father,并插入到list,在list中也只是空数据而已。
然后你从list中取出的数据是father类的实例,你强转到son本来就是错误的操作,虽然C++语法上是支持的,不过C++很明显的说明了,这种情况下要用户来保证其数据的有效性,否则形为是未定义的。
不要随意要父亲转换为子类,除非你明确知道父亲的对象其存储的内容为子类。
在你的例子中,从list取出的father来访问son 的x和y成员其实已经是内存越界了。
热心网友 时间:2023-10-15 20:28
将子类对象直接赋值给父类对象时,只有子类中继承的父类成员才会被复制,子类自己的成员不会被复制,这就是对象截断。
你的aa.push_back(bb),其实就是将bb这个子类对象复制给了list<father> aa中的一个父类对象,子类的数据成员当然不会复制了。
至于你将aa中的father类对象强制转化为son类对象时,对应的x,y成员是随机的。
热心网友 时间:2023-10-15 20:29
Adds a new element at the end of the vector, after its current last element. The content of this new element is initialized to a copy of x.
为son和father各添加一个拷贝构造函数,试试!
热心网友 时间:2023-10-15 20:27
C++父类和子类对象指针之间的转换
C++父类和子类对象指针之间的转换,有示例代码
C++父类和子类对象指针之间的转换
由子类向父类转换很简单, 用默认转换.
例如 CWnd* pWnd = (CWnd*)(&ChildView);
由父类向子类, 用dynamic_cast. 使用dynamic_cast是有*的.
例如对如下语句:
CPoint3D* p1 = dynamic_cast(p);
1.p虽然是CPoint类型, 但是p应当实际指向一个CPoint3D对象. 如果p实际指向的不是一个CPoint3D对象,则转换后的返回值为NULL.
2.VC中必须在project setting中设定/GR选项, 即Enable Runtime Type Identification(RTTI).
下面是一段示例代码:
#include <iostream>
using namespace std;
class CPoint
{
public:
virtual void f(){cout << "CPoint::f" <<endl;}
};
class CPoint3D : public CPoint
{
public:
virtual void f(){cout << "CPoint3D::f" <<endl;}
};
int main()
{
CPoint point,*pPoint;
CPoint3D point3D,*pPoint3D;
//子类向父类类型转换,直接强制转换就可以了,但实际仍然指向子类对象
pPoint = (CPoint*)&point3D;
pPoint->f(); //调用的仍然是子类的函数,这便是虚函数的魅力所在
//父类向子类类型转换,要用dynamic_cast
pPoint3D = dynamic_cast(pPoint);
pPoint->f(); //pPoint实际指向一个CPoint3D对象,故可以正确转换
pPoint3D = dynamic_cast(&point);
cout << (int*)pPoint3D << endl; //&point指向的不是一个CPoint3D对象,返回值为NULL
return 0;
}
运行结果为:
CPoint3D::f
CPoint3D::f
00000000
热心网友 时间:2023-10-15 20:28
father类没有任何成员,你能看到什么数据呢?它只是一个空类
将bb转换到父类father,并插入到list,在list中也只是空数据而已。
然后你从list中取出的数据是father类的实例,你强转到son本来就是错误的操作,虽然C++语法上是支持的,不过C++很明显的说明了,这种情况下要用户来保证其数据的有效性,否则形为是未定义的。
不要随意要父亲转换为子类,除非你明确知道父亲的对象其存储的内容为子类。
在你的例子中,从list取出的father来访问son 的x和y成员其实已经是内存越界了。
热心网友 时间:2023-10-15 20:28
将子类对象直接赋值给父类对象时,只有子类中继承的父类成员才会被复制,子类自己的成员不会被复制,这就是对象截断。
你的aa.push_back(bb),其实就是将bb这个子类对象复制给了list<father> aa中的一个父类对象,子类的数据成员当然不会复制了。
至于你将aa中的father类对象强制转化为son类对象时,对应的x,y成员是随机的。
热心网友 时间:2023-10-15 20:29
Adds a new element at the end of the vector, after its current last element. The content of this new element is initialized to a copy of x.
为son和father各添加一个拷贝构造函数,试试!