使用动态强制转换为派生类内的变量返回不同的值

pol*_*ism 1 c++ dynamic-cast

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

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;
    }
};
Run Code Online (Sandbox Code Playgroud)

Jon*_*ely 5

问题是你如何定义其他类:

class Package
{
    class Video_Games {}; //defined the classes
    class Genius_Phone {};
    class Sausage {};
    class Albums {};
Run Code Online (Sandbox Code Playgroud)

这些是嵌套类型,在里面Package.您已经定义了一个Package::Video_Games没有基类而没有成员的类.该dynamic_cast表达式使用这些类型,这是不是源自Package:

        if (dynamic_cast<Video_Games*>(this)) 
            return 4.99;
Run Code Online (Sandbox Code Playgroud)

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

后来你定义一个新的类型名称相同,即都是来源于Package:

class Video_Games :public Package
{
Run Code Online (Sandbox Code Playgroud)

但这是一种新型.Video_Games与...不是同一类型Package::Video_Games.定义派生包对象时,它将使用此类型,而不是转换使用的类型.所以你的演员阵容永远不会成功.

在定义了所有其他类型之后,您需要删除内部嵌套类型的定义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))
    // ...
}
Run Code Online (Sandbox Code Playgroud)

(但正如评论所说,这是定义多态接口的一种非常糟糕的方式 - 它会破坏虚函数的整个目的.)