【问题标题】:What happens when an upcast pointer is passed by reference to a function expecting derived?当向上转换指针通过引用传递给期望派生的函数时会发生什么?
【发布时间】:2011-06-29 01:16:11
【问题描述】:

我继承了类似于此代码的内容:

class Base
{
   public:
   virtual double getElement(int i) {return NULL;}
   virtual Derived*  GetAsDerived() {return this;}
};

class Derived : public Base
{
   public:
      virtual double getElement(int i) {return vec[i];}

   private:
   std::vector<double>;
};

还有一个函数如下:

void f(Base& b)
{
   Derived*  d = b.GetAsDerived();
}

程序流程是这样的

Derived A;
/*  get data into vector in A */

f(A);

f 中调用GetAsDerived() 之后。d 指向的对象中的向量包含垃圾。在调试器内部,我可以返回调用堆栈,看到A 内部的向量仍然有有效数据。

我确信所有这些奇怪的向上转换 - 向下转换是原因,但我无法在规范或在线找到正式的解释。

那么为什么它会以这种方式失败呢?

【问题讨论】:

  • 这段代码甚至无法编译。请贴出真实的,编译代码。
  • 我不能发布实际代码,它跨越了几个文件,这段代码只是为了注释问题
  • 是的,这没有任何意义 - 基类似乎没有 GetAsderived 函数,因此代码不适用于初学者。 GEtAsDerived 似乎也没有返回指针,所以这也不起作用。
  • @Eli:然后发布一些可以编译并演示您遇到的问题的代码。这个GetAsDerived() 不会编译,因为它试图返回this,它是Base*,而不是Derived*
  • 您的固定示例仍然是错误的。

标签: c++ inheritance casting


【解决方案1】:

向上转换在标准的 4.10/3 中正式定义。向下转换在 5.2.9/5 中,虽然这不是你具体在做什么。

解决您问题的标题,不可能将基类指针传递(或返回)到(从)参数(返回类型)指示派生类指针的函数。如果参数指示对基类指针的引用,则不可能通过引用传递派生类指针。如果是基类指针值,由于隐式转换,可以传递派生指针。

我无法说明您的代码失败的原因:如上所述,您的真实代码必须因与示例代码不同的原因而失败,因为您的示例代码根本不起作用。

【讨论】:

  • 具体来说,通过非常量引用...const 引用可以接受子类型就好了。
  • @Ben:好点,我忘了考虑那个。引用不会指向作为参数提供的派生指针,但当然引用仍然是同一个对象(或者无论如何是同一个对象的基类子对象),所以它很重要。
  • 无法理解“如果是基类指针值”。@BenVoigt@Steve Jessop
【解决方案2】:

函数中f,Derived* d = b.GetAsDerived();并没有改变b的任何内容,所以不能改变b指向的对象,在这种情况下A.在f中,如果有b = d或类似的东西,那么 A 会被改变。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2014-04-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-04-07
    • 2012-12-26
    • 2019-11-12
    • 1970-01-01
    相关资源
    最近更新 更多