c++ - 使用动态转换为派生类中的变量返回不同的值

标签 c++ dynamic-cast

试图找到一种方法让我的动态转换工作,但我不断收到运行时错误。它在打印出来时跳转到 else 语句 block 值(当它应该是一个 if block 值时,但当我在派生类中调用它时甚至没有使用它。所以它显示错误的值并且在计算。这是为什么?感谢您的帮助。

class Package
{
protected:
    string name_and_address = "?";

    double cost = 0.0;
    double discount = 0.0;
    double discount_rate = 0.0;

    bool overnight_delivery = false;
    bool insured = false;

    string package_contents = "?";

    double shipcost = 0.0;

public:
    Package() {};
    ~Package() {};

protected:
    virtual double calculate_cost() = 0;

    class Video_Games {}; //defined the classes
    class Genius_Phone {};
    class Sausage {};
    class Albums {};

    // here I'm trying to change "shipcost" inside each of the derived classes
    // to their respective and appropriate dollar values.
    // However, I am getting a runtime error wherein it will jump DIRECTLY
    // to the else statement 50.00 value for Video_Games
    // and not even calculate the value as 50.00. SO it's doubly useless.
    // It just skips to the else value and doesn't even factor
    // that into the Video_Games calculation when I try to test it. 
    virtual double shipping_cost() {
        if (dynamic_cast<Video_Games*>(this)) 
            return 4.99;
        else if (dynamic_cast<Genius_Phone*>(this))
            return 25.00;
        else if (dynamic_cast<Sausage*>(this))
            return 9.00;
        else
        {
            // should be assigned to class Albums,
            // but is somehow being triggered by class Video_Games.
            // Not sure why this is. 
            return 50.00; 
        }
    }
};

class Video_Games :public Package
{
private:
    int num_games = 0;

public:
    Video_Games(string location, int number_of_games, bool express, bool insurance)
    {
        num_games = number_of_games;
        name_and_address = location;
        overnight_delivery = express;
        insured = insurance;

        package_contents = to_string(num_games) + " Video Game(s)";

        cost = calculate_cost();
        discount = calculate_discount();
        shipcost = shipping_cost();
    }

    ~Video_Games() {};

protected:

    double calculate_cost()
    {
        cost = num_games * 19.99;
        // this is where the magic should happen.
        // shipcost here should be 4.99, but instead it's not even being used here.
        // In fact - it's empty. I'm not sure why shipcost
        // when set equal shipping_cost() is not returning that appropriate value.
        // Very baffling. 
        if (overnight_delivery) { cost += shipcost; } 
        if (insured) { cost *= 1.06; }

        return cost;
    }
};

最佳答案

问题在于您如何定义其他类:

class Package
{
    class Video_Games {}; //defined the classes
    class Genius_Phone {};
    class Sausage {};
    class Albums {};

这些是嵌套类型,位于 Package 中。您已经定义了一个没有基类和成员的类 Package::Video_Gamesdynamic_cast 表达式使用这些 类型,它们不是从Package 派生的:

        if (dynamic_cast<Video_Games*>(this)) 
            return 4.99;

Package::shipping_cost() 函数中的名称查找找到 Package::Video_Games 类型,它是没有基类或成员的空类。对象永远不是那种类型,因为 Package::Video_Games 不是从 Package 派生的,所以 this 类型的指针 Package* 不能指向 Package::Video_Games 类型的对象。

稍后您定义具有相同名称的新类型,Package 派生的:

class Video_Games :public Package
{

但这是一种新类型。 Video_GamesPackage::Video_Games 不是同一类型。当您定义派生包对象时,它将使用此类型,而不是强制转换使用的类型。所以你的 Actor 永远不会成功。

您需要删除 Package 中嵌套类型的定义,并将 Package::shipping_cost() 函数的主体移到类之外,毕竟其他类型已被定义(因此编译器已经看到那些其他类型的定义并且知道它们是从 Package 派生的)。

class Package
{
  virtual double shipping_cost();
  // ...
};

class Video_Games : public Package
{
  // ...
};

// Now you can define the virtual function:
double Package::shipping_cost()
{
  if (dynamic_cast<Video_Games*>(this))
    // ...
}

(但正如评论所说,这是定义多态接口(interface)的一种非常糟糕的方式——它违背了虚函数的全部目的。)

关于c++ - 使用动态转换为派生类中的变量返回不同的值,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42434528/

相关文章:

c++ - 我的 SDL/C++ 程序是否占用了过多的 RAM 内存?

c++ - 部分专业建议

c++ - 如何从父模板函数访问子成员?

c++ - 两个 dynamic_cast 问题

c++ - 无效 C 风格强制转换后的方法调用

c++ - 我误用了继承权吗?

c++ - 在 Android 上移植 native C++ 非静态二进制文件

c++ - 辅助函数 : static in cpp or define as static helper class method

c++ - 我们如何使用 STL 容器有效地存储对象? (即根据字段的值进行搜索)

c++ - 将以 execv 启动的进程重定向到/dev/null