C++ 风格的转换运算符是不是会更改它转换的指针?
Posted
技术标签:
【中文标题】C++ 风格的转换运算符是不是会更改它转换的指针?【英文标题】:Does a C++ style cast operator change the pointer it casts?C++ 风格的转换运算符是否会更改它转换的指针? 【发布时间】:2012-07-24 00:41:25 【问题描述】:我很高兴在我的代码中使用 C++ 风格的转换运算符,但我不能说我真正了解幕后发生的事情。我基本上想知道在以下简短过程中指针实际发生了什么:
class A ;
class B : public A ;
class C : public B ;
A* pC = new C();
B* b = static_cast<B*>(pC); // Is the value of pC changed by the cast?
C* c = static_cast<B*>(pC); // Is the value of pC changed by the cast?
B* b2 = static_cast<B*>(c) // Is the value of c now equal to the value of b2?
我意识到pC
指向的对象始终是C
类型,但在第一次转换后,我假设b
中存储的地址不再等于pC
中的地址。但是如果演员表改变了pC
的值,我的假设是错误的。简而言之,强制转换运算符真的可以改变他们强制转换的指针的地址吗?这似乎是一个非常简单的问题,但在我看来,图片只是不清楚具有继承层次结构的对象如何存储在内存中,以及指针如何通过强制转换进行操作。
在我的脑海中,pC
的值无论对其执行多少次强制转换都保持不变,但这种想法是否正确?
【问题讨论】:
有点不清楚你所说的“改变”是什么意思。 static_cast 是一个函数。它接受一个值并返回一个新值。 “更改”是指新值可能与旧值不同? @VaughnCato 我期待返回的演员表分配的新指针不同,我想知道演员表是否影响传递给演员表的指针(在本例中为 pC)。我以静态转换为例,但我真的想知道是否任何转换都能够修改其指针-我想我要问的是转换是否将参数视为按值传递(或 const ref)-即不能修改它。 是的,static_cast的参数是传值。 【参考方案1】:转换后的指针可以指向另一个位置。例如,在多重继承的情况下。 Good read
原来的指针会被保留
【讨论】:
我一直在等待这个答案。【参考方案2】:在任何情况下,强制转换都不会改变它的操作数。它所做的只是改变编译器查看操作数的方式。
pC
的值不会改变;强制转换的 result 可能是相同的值但类型不同(例如在 const_cast
或 reinterpret_cast
的情况下),或者它实际上可能是不同的类型 和 一个不同的值(例如,在多重继承的情况下,static_cast
,请参阅 Andrew 的答案)。
要真正了解在哪些情况下会出现不同的结果值,您必须阅读 C++ ABI,即对象如何准确地存储在内存中。
【讨论】:
虽然操作数确实永远不会改变,但static_cast<int>(0.1)
的结果并不意味着0.1
的“看到”有任何不同。
@LucDanton:一般情况下。例如,reinterpret_cast<int>("123")
(哦,人性!)被“视为”为 int。 const_cast
的结果被“视为”为非常量。这就是我所指的。
“在一般情况下”的措辞远没有“在任何情况下”那么强烈。你可能想解决这个问题。
@LucDanton:您非常依赖非母语人士。我会试着改写一下,好吗?
我没有曲解。这是我对阅读您的回答的诚实反应:我认为您的意思是,演员不仅从不改变操作数,而且总是改变操作数的方式可见。既然这不是您的意思(您确实说过“在一般情况下”),那么在我看来,最好的做法是选择明确的措辞。这一直是为了改进答案(因为我们在 cmets 中),我不是在询问演员表——我知道它是如何工作的。【参考方案3】:
在你的情况下,它不会改变指针。
但是对于多重继承,它必须改变指针。
您可以编写一个示例程序来确认这一点。
【讨论】:
【参考方案4】:简答:
通过强制转换,您只需告诉编译器如何解释一个对象,即我应该认为该对象是什么类型。
强制转换不会改变对象的值。
【讨论】:
虽然技术上正确,但您的回答具有误导性。将指针转换为类实例可能会返回与转换后的指针所包含的不同的指针地址。以上是关于C++ 风格的转换运算符是不是会更改它转换的指针?的主要内容,如果未能解决你的问题,请参考以下文章