C ++ ISO标准对解除引用指针的解释

时间:2011-09-14 17:17:02

标签: c++ pointers standards iso dereference

我想知道关于取消引用指向base的标准的标准视图,但我找不到任何进展。以这两个类为例:

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?
}

所以,基本上,如果对类型D的对象的类型B的指针被解除引用,那么切片是否会发生到位,或者临时会出现?我倾向于认为临时不是一种选择,因为这意味着临时是抽象类的实例。

无论事实如何,我都会感谢任何指向ISO标准的指示。 (或者第三,就此而言。:))

编辑:

我认为暂时不能作为一种选择,因为它可能的行为方式为什么它的行为方式,这是合乎逻辑的,但我找不到标准的确认,我不是一个普通的读者

EDIT2:

通过讨论,很明显我的问题实际上是解除引用指针机制,而不是关于拼接或临时。我感谢大家试图为我愚蠢,我终于得到了最让我困惑的问题的答案:为什么我在标准中找不到任何关于这个...显然这是错误的问题,但我得到了正确的答案。

日Thnx

3 个答案:

答案 0 :(得分:4)

Base &b = *static_cast<Base *>(d); // does this work by standard?

但你可以这样做:

Base &b = *d;

//use b polymorphically!
b.do_something(); //calls Derived::do_something()

无需使用static_cast。毕竟,Derived来自Base


回复你的编辑:

foo2(d); // does this work by standard?

是。可以使用类型Base*的指针初始化类型Derived*的指针。

-

Base &b = *b; // how this work by standard?

没有。他们的名字相同。如果你的意思是,Base &b1 = *b,那么是的,这是有效的。 b1指的是b指向的对象。

答案 1 :(得分:2)

在我的C ++ 11草案中,10 [class.derived] / 1表示

  

[注意:范围解析运算符::(5.1)可用于引用   明确的直接或间接基础成员。这允许访问   已在派生类中重新声明的名称。派生类   它本身可以作为受访问控制的基类;见11.2。   指向派生类的指针可以隐式转换为指针   到一个可访问的明确基类(4.10)。 a的左值   派生类类型可以绑定到对可访问的引用   明确的基类(8.5.3)。 - 后注]

在大多数实现中,您的foo2函数会将Base& b存储为Base*。它显然不能是Base本身,因为那将是一个副本,而不是一个参考。由于它(在运行时,不是语法上)就像指针而不是副本一样,因此没有拼接问题。

在编辑之前的代码中,编译器会知道Base& b实际上是d,它会是语法糖,甚至不会在程序集中生成指针。

答案 2 :(得分:2)

只有当基类的复制构造函数或赋值运算符以某种方式涉及时,才会发生对象切片,就像参数传递值一样。例如,即使仅在DEBUG模式下,您也可以通过继承Boost的noncopyable来轻松避免这些错误。

铸造指针或引用以及解除引用都不涉及任何复制构造或赋值。从Derived引用中创建Base引用是非常安全的,它甚至是标准的隐式转换。