【问题标题】:Casting a variable passed by reference in C++在 C++ 中转换通过引用传递的变量
【发布时间】:2015-08-20 15:42:17
【问题描述】:

我有一些通过引用传递变量的代码,但不会像我期望的那样导致在调用代码中更新变量;

// Interface classes
class Animal{};

class Car{
public:
    virtual void testDrive(Animal &animal) = 0;
};


// A specific implementation
class Bear : public Animal{
public:
    int testthing = 0;
};

void Ferrari::testDrive(Animal &animal){
    Bear b = dynamic_cast<Bear &>(animal);

    b.testthing = 1;
}


// Use those classes, doesn't need to know about Bear or Ferrari
int main()
{
    // Set up myCar and myAnimal

    myCar.testDrive(myAnimal)  // ** but myAnimal is unchanged! **
}

我实际上已经能够通过传递一个指针来让它工作(myAnimal 更新为testthing = 1),但我很想知道这里发生了什么。

据我了解,通过引用传递变量与传递指针密切相关,并且“关于多态性,引用就像指针一样工作”*。

那么为什么一个有效而另一个无效呢?有没有一种简单的方法可以让它与参考一起使用?

*Are references and pointers equal with regards to polymorphism?

编辑:这只是说明我的意思的一个例子,显然不是生产代码。

【问题讨论】:

  • P.S.:为熊驾驶汽车的混合比喻道歉;)
  • Bear b = dynamic_cast&lt;Bear &amp;&gt;(animal); 进行复制。你可能想要Bear&amp; b = dynamic_cast&lt;Bear &amp;&gt;(animal);
  • 好的,谢谢。指针似乎不会发生同样的情况,您能解释一下原因吗,以及是否有办法通过引用使其工作?
  • 顺便说一句,谁投了反对票,我能问为什么吗?如果这个问题有问题,我想在以后避免它。
  • 我猜myCarmyAnimal 缺少分号 + 缺少声明 = 否决票(虽然我只能猜测,不是我)

标签: c++


【解决方案1】:

Bear b = dynamic_cast&lt;Bear &amp;&gt;(animal); 正在获取animal 的强制转换值的值副本,因此对b 的修改不会影响原始值。

你想要Bear&amp; b = dynamic_cast&lt;Bear &amp;&gt;(animal);。那么b 本身就是一个引用。

请注意,如果 dynamic_cast 在进行引用转换时失败,则抛出 std::bad_cast。你应该妥善处理。

【讨论】:

  • 好的,谢谢!并感谢关于 bad_cast 的说明。所以这只适用于引用转换,对于指针,您可以使用if (b) { doSomeStuff() } 检查是否为空,对吧? (来自bogotobogo.com/cplusplus/upcasting_downcasting.php
  • 确实如此。如果结果指针将 truenullptr 进行比较,则 dynamic_cast 指针转换失败。
【解决方案2】:

我不是 100% 确定问题是什么。正常铸造工作正常:

#include <iostream>
using namespace std;
// Interface classes
class Animal{};

class Car{
public:
    virtual void testDrive(Animal &animal) = 0;
};

class Ferrari : public Car {
public:
    void testDrive(Animal &animal);
};


// A specific implementation
class Bear : public Animal{
public:
    int testthing = 0;
};


    void Ferrari::testDrive(Animal &animal){
        Bear & b = (Bear &) animal;

        b.testthing = 1;
    }


// Use those classes, doesn't need to know about Bear or Ferrari
int main()
{
// Set up myCar and myAnimal
    Animal myAnimal;
    Ferrari myCar ;
myCar.testDrive(myAnimal);  // ** but myAnimal is unchanged! **
cout << ((Bear &)myAnimal).testthing ;

}

打印: 1

【讨论】:

  • 正如 Bathsheba 指出的那样,我在演员阵容中复制了一份 - 我没有意识到要转换引用,您需要将变量明确定义为引用,因此 Bear &amp; b 而不是 @ 987654323@。谢谢。
猜你喜欢
  • 2012-10-15
  • 1970-01-01
  • 1970-01-01
  • 2011-08-11
  • 1970-01-01
  • 2011-12-06
相关资源
最近更新 更多