B
B
BobJonstone2020-01-03 22:40:29
OOP
BobJonstone, 2020-01-03 22:40:29

Upcast array of derived class to parent?

There are two classes base_Class(parent) and derived_Class(child)
There is some virtual function in base_Class that takes as a parameter an array of class objects f(base_Class **mass)
To use this function for a derived class, you need to cast the array of the derived class to the array of the parent
Arrays : base_Class *baseMass[100], derived_Class *derivedMass[100]
How to perform this cast?

Answer the question

In order to leave comments, you need to log in

1 answer(s)
M
Mercury13, 2020-01-04
@BobJonstone

Why not: if we declare a box of bananas as a box of fruit and put an apple in it, it will no longer be a box of bananas.

#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;
}

Didn't find what you were looking for?

Ask your question

Ask a Question

731 491 924 answers to any question