指针类型经过cast后,指针的值是否变化呢?

adolthor 2010-07-06 07:37:41
比如说
p1 = static_cast<T1*>(p2);

p1 = dynamic_cast<T1*>(p2);
在转换成功的情况下,p1是否一定等于p2呢?

我遇到的问题是,用malloc申请了一个对象的内存,但是这个对象可以拥有相对复杂的继承关系,并且允许多重继承,在使用的时候我会将它转换成基类指针,如果基类指针不等于原对象的指针,我就无法free掉了。
...全文
733 26 打赏 收藏 转发到动态 举报
AI 作业
写回复
用AI写文章
26 条回复
切换为时间正序
请发表友善的回复…
发表回复
na2650945 2010-07-07
  • 打赏
  • 举报
回复
[Quote=引用 5 楼 nossiac 的回复:]

指针的cast前后仍然指向同一个地址,其指向的空间的意义改变了。
[/Quote]
认同这个。
失落的凡凡 2010-07-07
  • 打赏
  • 举报
回复
[Quote=引用 20 楼 peige2008 的回复:]
你们2个就是答非所问,,,我受不了你们。。
[/Quote]

人家都说了这个对象有复杂的继承关系了,还可能有多重继承。

[Quote=引用楼主 adolthor 的回复:]
我遇到的问题是,用malloc申请了一个对象的内存,但是这个对象可以拥有相对复杂的继承关系,并且允许多重继承,在使用的时候我会将它转换成基类指针,如果基类指针不等于原对象的指针,我就无法free掉了。
[/Quote]

pengzhixi 2010-07-07
  • 打赏
  • 举报
回复
没什么好争的,去看看effective c++就知道了,和编译器对象的布局是有关系的,所以在使用dynamic_cast的时候有的编译器会调整指针的位置,有的不会。
loongee 2010-07-07
  • 打赏
  • 举报
回复
[Quote=引用 22 楼 peige2008 的回复:]

你这人就是:人家叫你拿枪去杀敌人,你硬要拿把菜刀去砍。
[/Quote]

是楼主自己在强调说他有复杂的继承结构而且还支持多重继承嘛,要不咱咋会想那么多哩!
PG 2010-07-07
  • 打赏
  • 举报
回复
你这人就是:人家叫你拿枪去杀敌人,你硬要拿把菜刀去砍。
loongee 2010-07-07
  • 打赏
  • 举报
回复
To 20楼:

不多说,直接上代码

#include <iostream>
using namespace std;

class A
{
public:
int a;
};

class B
{
int b;
};

class C:public A, public B
{
int c;
};

int main()
{
C cIns;
C* p2 = &cIns;
B* p1 = NULL;
p1 = static_cast<B*>(p2);
cout << p1 << ' ' << p2 << endl;
p1 = dynamic_cast<B*>(p2);
cout << p1 << ' ' << p2 << endl;
system("pause");
return 0;
}


自己试下吧。
PG 2010-07-07
  • 打赏
  • 举报
回复
[Quote=引用 17 楼 loongee 的回复:]
引用 16 楼 djjlove_2008 的回复:

  首先跟你说个最基本的问题:static_cast<>(),dynamic_cast<>(),C++把类型转换设计得如此复杂,实际上就是告诉我们,转换始终不好,在大的系统中会产生各种各样的问题。
针对你的问题一:,p1是否等于p2,我们从逻辑上分析,p1先系统分配给它一个地址,p2也是,我们大脑中有内存图的概念,p1,p2的地址不一样,……
[/Quote]
[Quote=引用 13 楼 milkylove 的回复:]
11楼和12楼:

不要想当然,不确定就不要乱发言。不信请试一下9楼做的试验。
[/Quote]

RE:13&16楼的孩子,,要好好看书,,还有,带多个眼镜。

楼主问题:
p1 = static_cast<T1*>(p2);

p1 = dynamic_cast<T1*>(p2);
在转换成功的情况下,p1是否一定等于p2呢?

9楼特殊案例:
p1 = static_cast<A*>(p2);

p1 = dynamic_cast<B*>(p2);
在转换成功的情况下,p1是否一定等于p2呢?


A=B?我受不了你们2个。。。

谁不知道这样多重继承,2个基class在 子class对象中的布局顺序不同啊,,

你们2个就是答非所问,,,我受不了你们。。




pengzhixi 2010-07-07
  • 打赏
  • 举报
回复
#include<iostream>
using namespace std;


struct Test{
virtual ~Test(){};
int a;
};
struct Test1{
virtual ~Test1(){};
int b;
};
struct Drived:public Test,public Test1{
virtual ~Drived(){};
int c;
};
int main()
{
Test1 *p=new Drived;
Drived*ptr=dynamic_cast<Drived*>(p);
cout<<(void*)p<<" "<<(void*)ptr<<endl;

system("pause");
return 0;
}

这里是一个简单的实例
pengzhixi 2010-07-07
  • 打赏
  • 举报
回复
用dynamic_cast的话,有的会有变化,可能会调整指针指向的位置。
loongee 2010-07-07
  • 打赏
  • 举报
回复
[Quote=引用 16 楼 djjlove_2008 的回复:]

  首先跟你说个最基本的问题:static_cast<>(),dynamic_cast<>(),C++把类型转换设计得如此复杂,实际上就是告诉我们,转换始终不好,在大的系统中会产生各种各样的问题。
针对你的问题一:,p1是否等于p2,我们从逻辑上分析,p1先系统分配给它一个地址,p2也是,我们大脑中有内存图的概念,p1,p2的地址不一样,你把他们强制转换了,他们会相等吗,至少地址不可能一样。
……
[/Quote]

你貌似没理解到楼主的意思吧。p1和p2是可能一样的哦。

To 11楼和12楼:不要想当然,你们误人子弟了……
djjlove_2008 2010-07-06
  • 打赏
  • 举报
回复
  首先跟你说个最基本的问题:static_cast<>(),dynamic_cast<>(),C++把类型转换设计得如此复杂,实际上就是告诉我们,转换始终不好,在大的系统中会产生各种各样的问题。
  针对你的问题一:,p1是否等于p2,我们从逻辑上分析,p1先系统分配给它一个地址,p2也是,我们大脑中有内存图的概念,p1,p2的地址不一样,你把他们强制转换了,他们会相等吗,至少地址不可能一样。
  对于问题二:关于无法free掉的问题,应该把析构函数设计成virtual就行了吧,这样的多态性可以满足不产生内存泄漏。

  
ahao 2010-07-06
  • 打赏
  • 举报
回复
可能会变
liutengfeigo 2010-07-06
  • 打赏
  • 举报
回复
失落的凡凡 2010-07-06
  • 打赏
  • 举报
回复
11楼和12楼:

不要想当然,不确定就不要乱发言。不信请试一下9楼做的试验。
PG 2010-07-06
  • 打赏
  • 举报
回复

p1 = static_cast<T1*>(p2);

p1 = dynamic_cast<T1*>(p2);
在转换成功的情况下,p1是否一定等于p2呢?

一定。。

呵呵,在C++里玩C管理内存,还用多重继承做实验,有没有用上多态了??

此人必火
hengshan 2010-07-06
  • 打赏
  • 举报
回复
不管你怎么转换,指针的值是不变的。只会影响编译器对指针所指向内容的理解。
adolthor 2010-07-06
  • 打赏
  • 举报
回复
析构不是问题,很好解决,而我内存管理的策略是C接口的,C接口在释放内存时必须获得原始地址。貌似4楼说的是正确的,测试一下正确后结贴
cattycat 2010-07-06
  • 打赏
  • 举报
回复
析构函数中加上输出.
#include <iostream>
using namespace std;

class A
{
public:
virtual ~A(){cout<<"A destructor"<<endl;}

};
class B
{
public:
virtual ~B(){cout<<"B destructor"<<endl;}
};
class C:public A,public B
{
public:
virtual ~C(){cout<<"C destructor"<<endl;}
};
int main () {

C *c=new C;
A *a=static_cast<A*>(c);
B *b=static_cast<B*>(c);
cout<<c<<" "<<a<<" "<<b<<endl;
delete b;
return 0;
}


vs08中输出:
00395C50 00395C50 00395C54
C destructor
B destructor
A destructor

可以看到B的指针值被调整了,当然如果你析构函数声明为虚函数的话,会调用正确的析构函数释放空间。
失落的凡凡 2010-07-06
  • 打赏
  • 举报
回复
灵异事件……

7楼显示的回贴时间比我在6楼的回复还早两秒……
失落的凡凡 2010-07-06
  • 打赏
  • 举报
回复
这样的话最好不要用malloc。
可以用new,并把类的析构函数声明为virtual。
加载更多回复(6)

65,201

社区成员

发帖
与我相关
我的任务
社区描述
C++ 语言相关问题讨论,技术干货分享,前沿动态等
c++ 技术论坛(原bbs)
社区管理员
  • C++ 语言社区
  • encoderlee
  • paschen
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
  1. 请不要发布与C++技术无关的贴子
  2. 请不要发布与技术无关的招聘、广告的帖子
  3. 请尽可能的描述清楚你的问题,如果涉及到代码请尽可能的格式化一下

试试用AI创作助手写篇文章吧