1

我想知道标准对取消引用指向基址的指针的看法,但我在找到它方面没有任何进展。以这两个类为例:

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:

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

谢谢

4

3 回答 3

5
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

于 2011-09-14T17:20:12.240 回答
2

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

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

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

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

于 2011-09-14T17:26:36.400 回答
2

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

转换指针或引用或取消引用都不涉及任何复制构造或分配。从 Derived 引用创建 Base 引用是非常安全的,它甚至是标准的隐式转换。

于 2011-09-14T17:37:18.673 回答