在此具有以下示例代码:

#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <iostream>

namespace autos
{
    enum CarTypes
    {
        SUVType,
        SportType,
        UnknownType
    };

    class Car
    {
        public:
            Car();
            virtual ~Car();

            CarTypes type;
            int powerCV;
    };

    Car::Car()
    {
        type = CarTypes::UnknownType;
    }

    Car::~Car() {}

    class SUV : public Car
    {
        public:
            SUV();
            virtual ~SUV();

            bool fourXFour;
            int  trunkSizeLiters;
            bool dvdInBackSeat;
    };

    SUV::SUV()
    {
        type = CarTypes::SUVType;
        powerCV = 0;
        fourXFour = false;
        trunkSizeLiters = 0;
        dvdInBackSeat = false;
    }

    SUV::~SUV() {}

    class Sport : public autos::Car
    {
        public:
            Sport();
            virtual ~Sport();

            bool convertible;
            bool twoSeats;
            int  maxSpeed;
    };

    Sport::Sport()
    {
        type = autos::CarTypes::SportType;
        powerCV = 0;
        convertible = false;
        twoSeats = false;
        maxSpeed = 0;
    }

    Sport::~Sport() {}
} /* end namespace autos */


autos::Car ManufactureCar()
{
    srand(time(NULL));
    int typeCode = rand() % 2 + 1;

    if (typeCode == 1)
    {
        autos::SUV newSUV;
        newSUV.powerCV = 300;
        newSUV.fourXFour = true;
        newSUV.trunkSizeLiters = 500;
        newSUV.dvdInBackSeat = true;
        return newSUV;
    }

    autos::Sport newSport;
    newSport.powerCV = 550;
    newSport.maxSpeed = 300;
    newSport.twoSeats = true;
    newSport.convertible = true;
    return newSport;
}

int main(int argc)
{
    autos::Car newCar = ManufactureCar();

    if (newCar.type == autos::CarTypes::SportType)
    {
        std::cout << "A new SPORT car was manufactured: " << std::endl;

        autos::Sport& sportCar = dynamic_cast<autos::Sport&>(newCar);

        std::cout << "Power (CV): " << sportCar.powerCV << std::endl;
        std::cout << "Convertible: " << sportCar.convertible << std::endl;
        std::cout << "Maximum speed: " << sportCar.maxSpeed << std::endl;
        std::cout << "Two seats: " << sportCar.twoSeats << std::endl;
    }
    else if (newCar.type == autos::CarTypes::SUVType)
    {
        std::cout << "A new SUV car was manufactured: " << std::endl;

        autos::SUV& suvCar = dynamic_cast<autos::SUV&>(newCar);

        std::cout << "Power (CV): " << suvCar.powerCV << std::endl;
        std::cout << "4x4: " << suvCar.fourXFour << std::endl;
        std::cout << "Trunk size (Liters): " << suvCar.trunkSizeLiters << std::endl;
        std::cout << "DVD in backseats: " << suvCar.dvdInBackSeat << std::endl;
    }
    else
    {
        std::cout << "ERROR: Unknown car manufactured." << std::endl;
    }

}


我看过this post here,显示的程序可以编译,但是在调用Access violation时,它的确抛出了异常(dynamic_cast)。
我尝试使用指针:autos::SUV* suvCar = dynamic_cast<autos::SUV*)(&newCar),并且也遇到访问冲突。

为什么我不能将数据转换为派生类型?

有没有更好的方法来获取实类型,或者dynamic_cast是这里唯一/更好的选择?

[编辑-解决方案]

Problem solved using smart pointers:

std::shared_ptr<autos::Car> ManufactureCar()
{
    srand(time(NULL));
    int typeCode = rand() % 2 + 1;

    if (typeCode == 1)
    {
        autos::SUV newSUV;
        newSUV.powerCV = 300;
        newSUV.fourXFour = true;
        newSUV.trunkSizeLiters = 500;
        newSUV.dvdInBackSeat = true;

        auto ret = std::make_shared<autos::SUV>(newSUV);
        return std::dynamic_pointer_cast<autos::Car>(ret);
    }

    autos::Sport newSport;
    newSport.powerCV = 550;
    newSport.maxSpeed = 300;
    newSport.twoSeats = true;
    newSport.convertible = true;

    auto ret = std::make_shared<autos::Sport>(newSport);
    return std::dynamic_pointer_cast<autos::Car>(ret);
}

int main(int argc)
{
    std::shared_ptr<autos::Car> newCar = ManufactureCar();

    if (newCar->type == autos::CarTypes::SportType)
    {
        std::cout << "A new SPORT car was manufactured: " << std::endl;

        std::shared_ptr<autos::Sport> sportCar = std::dynamic_pointer_cast<autos::Sport> (newCar);

        std::cout << "Power (CV): " << sportCar->powerCV << std::endl;
        std::cout << "Convertible: " << sportCar->convertible << std::endl;
        std::cout << "Maximum speed: " << sportCar->maxSpeed << std::endl;
        std::cout << "Two seats: " << sportCar->twoSeats << std::endl;
    }
    else if (newCar->type == autos::CarTypes::SUVType)
    {
        std::cout << "A new SUV car was manufactured: " << std::endl;

        std::shared_ptr<autos::SUV> suvCar = std::dynamic_pointer_cast<autos::SUV> (newCar);

        std::cout << "Power (CV): " << suvCar->powerCV << std::endl;
        std::cout << "4x4: " << suvCar->fourXFour << std::endl;
        std::cout << "Trunk size (Liters): " << suvCar->trunkSizeLiters << std::endl;
        std::cout << "DVD in backseats: " << suvCar->dvdInBackSeat << std::endl;
    }
    else
    {
        std::cout << "ERROR: Unknown car manufactured." << std::endl;
    }

}

最佳答案

你在哪里
autos :: Car newCar = ManufactureCar();
在程序中,您仅为Car对象分配了足够的存储空间。您不能将其转换为需要更多存储空间的子类。

建议您修改ManufactoreCar()函数以在堆上创建适当的对象,并返回指向该对象的指针。

例如,

   if (typeCode == 1)
    {
        autos::SUV* x = new autos::SUV;
        x->powerCV = 300;
        x->fourXFour = true;
        x->trunkSizeLiters = 500;
        x->dvdInBackSeat = true;
        return x;
    }


这样,您的对象将已经为它们的类型正确分配。当然,您还将在以后的程序中使用指针来引用它们。我希望这有帮助。

10-06 02:06