c++ Проверете дали най-производният клас на базова референция има друга база

Ето примерен код на поведението, което бих искал да видя:

// Example program
#include <iostream>
#include <string>
#include <type_traits>
#include <vector>

class BaseA
{
public:
    BaseA() { };
};

class BaseB
{
public:
    BaseB() { };
};

class Derived1 : public BaseA
{
public:
    Derived1() : BaseA() { };
};

class Derived2 : public BaseA, public BaseB
{
public:
    Derived2() : BaseA(), BaseB() { };
};

int main()
{
    std::vector<BaseA *> collection_of_As{
        new Derived1{}, new Derived1{}, new Derived2{},
        new Derived2{}, new Derived1{}, new Derived2{}
        };

    for (BaseA * Aptr: collection_of_As) {
        BaseB * Bptr = dynamic_cast<BaseB *>(Aptr);

        std::cout << std::boolalpha << (Bptr != std::nullptr) << std::endl;
    }

    return 0;
}

Но няма да се компилира, тъй като BaseA не е полиморфен, въпреки че е най-производният клас, който може да бъде. Разбирам защо това не работи, но все още имам нужда от това поведение. Има ли начин да накарам това да се компилира и да работи?


person Brian Rodriguez    schedule 27.05.2015    source източник
comment
Защо не публикувате MCVE? Бяхте толкова близо. Просто трябваше да включите iostream и vector в горната част на този файл. Това ще улесни другите да възпроизведат вашия проблем и да работят върху него.   -  person David Grayson    schedule 27.05.2015
comment
Защо не го направите полиморфен, като дефинирате виртуален деструктор в BaseA?   -  person StenSoft    schedule 27.05.2015
comment
Друго хубаво нещо, което трябва да направите, е да включите точното съобщение за грешка, което получавате от компилатора, което е error: cannot dynamic_cast 'Aptr' (от тип 'class BaseA*') към тип 'class BaseB*' (изходният тип не е полиморфен ). Като извършите търсене в интернет за ключовите думи в това съобщение за грешка, можете да намерите други хора, които са имали абсолютно същия проблем като вас и са го разрешили, като са направили BaseA полиморфна: stackoverflow.com/questions/15114093/   -  person David Grayson    schedule 27.05.2015


Отговори (1)


Направете BaseA полиморфен. Най-лесният начин да направите това е да му дадете виртуален деструктор.

class BaseA
{
public:
    virtual ~BaseA() {}
};

Така или иначе ще ви е необходим такъв, ако искате да поправите изтичането на памет във вашия пример.

person Mike Seymour    schedule 27.05.2015
comment
Толкова просто! :) Благодаря ти - person Brian Rodriguez; 27.05.2015