C++解引用基址指针的 ISO 标准解释
我想知道标准对取消引用指向基点的指针的看法,但我在寻找它方面没有取得任何进展。以这两个类为例:
class Base
{
public:
virtual void do_something() = 0;
};
class Derived : public Base
{
public:
virtual void do_something();
};
void foo2(Base *b)
{
Base &b1 = *b; // how this work by standard?
}
void foo()
{
Derived *d = new Derived();
foo2(d); // does this work by standard?
}
那么,基本上,如果类型 B 的指针指向类型 D 的对象被取消引用,切片会就地发生,还是会出现临时的?我倾向于认为临时不是一个选项,因为这意味着临时是抽象类的实例。
无论真相如何,如果有人能指出 ISO 标准中的一个或另一个,我将不胜感激。 (或者第三个,就此而言。:) )
编辑:
我提出了暂时不作为一个选项的观点,作为推理为什么它的行为方式如此的可能路线,这是非常合乎逻辑的,但我找不到确认标准,而且我不是一个普通读者。
编辑2:
通过讨论,很明显我的问题实际上是关于取消引用指针机制,而不是关于拼接或临时。我感谢大家试图为我简化它,我终于得到了最让我困惑的问题的答案:为什么我在标准中找不到任何关于这个的内容......显然这是错误的问题,但我已经得到了正确的答案。
谢谢
I would like to know standard's view on dereferencing pointer to base, but I'm not making any progress finding it. Take these two classes for example:
class Base
{
public:
virtual void do_something() = 0;
};
class Derived : public Base
{
public:
virtual void do_something();
};
void foo2(Base *b)
{
Base &b1 = *b; // how this work by standard?
}
void foo()
{
Derived *d = new Derived();
foo2(d); // does this work by standard?
}
So, basically, if pointer of type B to an object of type D is dereferenced, will slicing happen in place, or temporary will emerge? I'm prone to believe that temporary is not an option, because that would mean that temporary is instance of abstract class.
Whatever the truth, I would appreciate any pointers to the ISO standard that says one or the other. (Or third, for that matter. :) )
EDIT:
I threw the point with temporary not being an option as a possible line of reasoning why it behaves the way it does, which is quite logical, but I can't find confirmation in standard, and I'm not a regular reader.
EDIT2:
Through discussion, it became obvious that my question was actually about dereferencing a pointer mechanism, and not about splicing or temporaries. I thank everyone for trying to dumb it down for me, and I finally got answer to the question the puzzled me the most: Why I can't find anything in the standard about this... Obviously it was the wrong question, but I've got the right answer.
Thnx
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
是的。
但你可以简单地这样做:
不需要使用
static_cast
。毕竟,Derived
是从Base
派生的。回复您的编辑:
是的。
Base*
类型的指针可以使用Derived*
类型的指针进行初始化。--
不,他们同名。如果您的意思是,
Base &b1 = *b
,那么是的,可以。b1
指的是b
所指向的对象。Yes.
But you can simply do this:
No need to use
static_cast
. After all,Derived
is derived fromBase
.Reply to your edit:
Yes. Pointer of type
Base*
can be initialized with pointer of typeDerived*
.--
No. They're same name. If you mean,
Base &b1 = *b
, then yes, that works.b1
refers to the object pointed to byb
.仅当基类的复制构造函数或赋值运算符以某种方式涉及时(例如按值传递参数),才会发生对象切片。例如,您可以通过继承 Boost 的
noncopyable
轻松避免这些错误,即使仅在 DEBUG 模式下也是如此。指针或引用的强制转换以及取消引用都不涉及任何复制构造或赋值。从派生引用创建基引用是完全安全的,它甚至是标准的隐式转换。
Object slicing only occurs when the copy constructor or the assignment operator of the base class gets involved somehow, like in parameter passing by value. You can easily avoid these errors by inheriting from Boost's
noncopyable
for example, even if only in DEBUG mode.Neither casting pointers or references nor dereferencing involve any copy construction or assignment. Making a Base reference from a Derived reference is perfectly safe, it's even a standard implicit conversion.
在我的 C++11 草案中,10 [class.driven] /1 表示
在大多数实现中,您的 foo2 函数将存储
Base& b
作为Base*
。显然它本身不可能是Base
,因为那将是一个副本,而不是引用。由于它的行为(在运行时,而不是语法上)类似于指针而不是副本,因此不存在拼接问题。在编辑之前的代码中,编译器会知道
Base& b
实际上是d
,它将是语法糖,甚至不会在程序集中生成指针。In my C++11 draft, 10 [class.derived] /1 says
In most implementations, your foo2 function will store
Base& b
as aBase*
. It obviously can't be aBase
itself, because that would be a copy, not a reference. Since it acts (at runtime, not syntactically) like a pointer instead of a copy, there's no splicing concerns.In your code before your edit, the compiler would know that
Base& b
was actuallyd
, it would be syntactic sugar, and wouldn't even generate a pointer in the assembly.