@BobJonstone

Восходящее преобразование массива производного класса к родительскому?

Есть два класса base_Class(родитель) и derived_Class(потомок)
Есть некая виртуальная функция в base_Class которая принимает в качестве параметра массив объектов класса f(base_Class **mass)
Чтобы воспользоваться данной функцией для производного класса, необходимо привести массив производного класса к массиву родительского
Массивы: base_Class *baseMass[100], derived_Class *derivedMass[100]
Как произвести такое приведение типов?
  • Вопрос задан
  • 117 просмотров
Решения вопроса 1
@Mercury13
Программист на «си с крестами» и не только
Почему нельзя: если мы объявим ящик бананов ящиком фруктов и положим туда яблоко, он перестанет быть ящиком бананов.
#include <iostream>

class Vocal {  // интерфейс
public:
    virtual void shout() = 0;
    virtual ~Vocal() = default;
};

class Dog : public Vocal {
public:
    virtual void shout() override { std::cout << "Woof!" << std::endl; }
};

class Unrelated {};

// ВАРИАНТ 1. Метод выкручивания рук.

void shoutAll_v1(Vocal** x, int n)
{
    for (int i = 0; i < n; ++i)
        x[i]->shout();
}

template <class T, int N>
inline void shoutAll_v1(T* (&x)[N]) {
    // Тупая проверка концепции, ждём Си++20
    static_assert (std::is_base_of<Vocal, T>(), "Need array of Vocal");
    T** xx = x;
    shoutAll_v1(reinterpret_cast<Vocal**>(xx), N);
}

// ВАРИАНТ 2. Виртуальный полиморфизм.

class Choir { // интерфейс
public:
    virtual int size() const = 0;
    virtual Vocal& at(size_t i) const = 0;
    virtual ~Choir() = default;
};

void shoutAll_v2(const Choir& x)
{
    int sz = x.size();
    for (int i = 0; i <sz; ++i)
        x.at(i).shout();
}

template <class T>
class VocalArray : public Choir {
public:
    template <int N>
    VocalArray(T* (&x)[N]) : fData(x), fSize(N) {}
    int size() const override { return fSize; }
    Vocal& at(size_t i) const override { return *fData[i]; }
private:
    T** const fData;
    int fSize;
};

int main()
{
    Dog* sons[3];
    for(auto& x : sons) {
        x = new Dog;
    }
    //Unrelated* unrel[3];

    std::cout << "V1" << std::endl;
    shoutAll_v1(sons);
    //shoutAll_v1(unrel);   не компилируется

    std::cout << "V2" << std::endl;
    shoutAll_v2(VocalArray<Dog>(sons));
    //shoutAll_v2(VocalArray<Unrelated>(unrel));  не компилируется

    return 0;
}
Ответ написан
Пригласить эксперта
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы