用子类指针指向父类对象,但只访问父类对象的成员,安全吗?

menzi11 2013-10-28 11:57:56
比如:
class A { public: int data;}

class B :public A {......}

B* ptr=(B*)new A;
ptr->data=10;

这样做安全吗? 保证不会访问到子类成员,标准中有相关规定吗?
...全文
324 16 打赏 收藏 转发到动态 举报
写回复
用AI写文章
16 条回复
切换为时间正序
请发表友善的回复…
发表回复
ri_aje 2013-10-29
  • 打赏
  • 举报
回复
引用 12 楼 menzi11 的回复:
[quote=引用 6 楼 ri_aje 的回复:]

B* ptr=(B*)new A;
已经导致为定义行为了,后面的访问都不行。
这样就UB了吗? 好简单.....[/quote] yep, and if you are interested, here is what the standard has to say. c++11 5.2.9/11 A prvalue of type “pointer to cv1 B,” where B is a class type, can be converted to a prvalue of type “pointer to cv2 D,” where D is a class derived (Clause 10) from B, if a valid standard conversion from “pointer to D” to “pointer to B” exists (4.10), cv2 is the same cv-qualification as, or greater cv-qualification than, cv1, and B is neither a virtual base class of D nor a base class of a virtual base class of D. The null pointer value (4.10) is converted to the null pointer value of the destination type. If the prvalue of type “pointer to cv1 B” points to a B that is actually a subobject of an object of type D, the resulting pointer points to the enclosing object of type D. Otherwise, the result of the cast is undefined.
menzi11 2013-10-29
  • 打赏
  • 举报
回复
引用 6 楼 ri_aje 的回复:

B* ptr=(B*)new A;
已经导致为定义行为了,后面的访问都不行。
这样就UB了吗? 好简单.....
menzi11 2013-10-29
  • 打赏
  • 举报
回复
引用 13 楼 ri_aje 的回复:
[quote=引用 12 楼 menzi11 的回复:] [quote=引用 6 楼 ri_aje 的回复:]

B* ptr=(B*)new A;
已经导致为定义行为了,后面的访问都不行。
这样就UB了吗? 好简单.....[/quote] yep, and if you are interested, here is what the standard has to say. c++11 5.2.9/11 A prvalue of type “pointer to cv1 B,” where B is a class type, can be converted to a prvalue of type “pointer to cv2 D,” where D is a class derived (Clause 10) from B, if a valid standard conversion from “pointer to D” to “pointer to B” exists (4.10), cv2 is the same cv-qualification as, or greater cv-qualification than, cv1, and B is neither a virtual base class of D nor a base class of a virtual base class of D. The null pointer value (4.10) is converted to the null pointer value of the destination type. If the prvalue of type “pointer to cv1 B” points to a B that is actually a subobject of an object of type D, the resulting pointer points to the enclosing object of type D. Otherwise, the result of the cast is undefined.[/quote] 经典!! 此贴终结!也感谢其他人 另外这标准在哪里可以看...
ztenv 版主 2013-10-29
  • 打赏
  • 举报
回复
这样做真的没什么意义,
ri_aje 2013-10-29
  • 打赏
  • 举报
回复
引用 14 楼 menzi11 的回复:
[quote=引用 13 楼 ri_aje 的回复:] [quote=引用 12 楼 menzi11 的回复:] [quote=引用 6 楼 ri_aje 的回复:]

B* ptr=(B*)new A;
已经导致为定义行为了,后面的访问都不行。
这样就UB了吗? 好简单.....[/quote] yep, and if you are interested, here is what the standard has to say. c++11 5.2.9/11 A prvalue of type “pointer to cv1 B,” where B is a class type, can be converted to a prvalue of type “pointer to cv2 D,” where D is a class derived (Clause 10) from B, if a valid standard conversion from “pointer to D” to “pointer to B” exists (4.10), cv2 is the same cv-qualification as, or greater cv-qualification than, cv1, and B is neither a virtual base class of D nor a base class of a virtual base class of D. The null pointer value (4.10) is converted to the null pointer value of the destination type. If the prvalue of type “pointer to cv1 B” points to a B that is actually a subobject of an object of type D, the resulting pointer points to the enclosing object of type D. Otherwise, the result of the cast is undefined.[/quote] 经典!! 此贴终结!也感谢其他人 另外这标准在哪里可以看...[/quote] 这里 (http://www.open-std.org/jtc1/sc22/wg21/) 有的 draft,标准的话,自己找找吧。
worldy 2013-10-28
  • 打赏
  • 举报
回复
引用 楼主 menzi11 的回复:
比如: class A { public: int data;} class B :public A {......} B* ptr=(B*)new A; ptr->data=10; 这样做安全吗? 保证不会访问到子类成员,标准中有相关规定吗?
肯定不安全,两个对象占用的空间是不一样的
turing-complete 2013-10-28
  • 打赏
  • 举报
回复
不安全,标准中没有这样的约定。 而且,我认为多继承的情况下,这很可能就错了。
漫步者、 2013-10-28
  • 打赏
  • 举报
回复
  • 打赏
  • 举报
回复
只访问基类的成员,倒是没有什么问题。 但是这样写,可读性不差。 首先,你要注意,访问的到底是不是基类的成员,访问的成员函数,是否被派生类override了? 与其这样,还不如直接用基类的指针。 起码基类的指针不会让你访问一个不属于基类的成员.
derekrose 2013-10-28
  • 打赏
  • 举报
回复
有什么意义呢?倒不如说一下你遇到的问题
Luisfan 2013-10-28
  • 打赏
  • 举报
回复
如果B中也有data的话,你这样是会出问题的
max_min_ 2013-10-28
  • 打赏
  • 举报
回复
显然没有直接对象类型安全!
Luisfan 2013-10-28
  • 打赏
  • 举报
回复
你这样强转过后,肯定是基类的啊.
mujiok2003 2013-10-28
  • 打赏
  • 举报
回复
答案:是不一定(考虑一下多继承的情况).
「已注销」 2013-10-28
  • 打赏
  • 举报
回复
如果要这么做,那么基类中会被调用的所有函数都声明为虚函数,否则看下面
#include <iostream>
using namespace std;

class TestBase
{
private:
	int a;
public:
	TestBase(){ a=0; }
	~TestBase(){}
	void print()
	{
		cout<<"TestBase print:"<<a<<endl;
	}
};

class TestOne:public TestBase
{
private:
	int a;
public:
	TestOne(){ a=1; }
	~TestOne(){}
	void print()
	{
		cout<<"TestOne print"<<a<<endl;
	}
};

int main(int argc, char* argv[])
{
	TestOne* one = (TestOne*)new TestBase;
	one->print();
	return 0;
}
ri_aje 2013-10-28
  • 打赏
  • 举报
回复

B* ptr=(B*)new A;
已经导致为定义行为了,后面的访问都不行。

64,646

社区成员

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

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