Upcast the array of the derived class to the parent?

There are two class base_Class(parent) and derived_Class(descendant)
There is a certain virtual function base_Class which takes as a parameter an array of objects of class f(base_Class **mass)
To use this function for a derived class, you must cast an array of a derived class to the parent array
Arrays: base_Class *baseMass[100], derived_Class *derivedMass[100]
How to make this type conversion?
April 4th 20 at 00:41
1 answer
April 4th 20 at 00:43
Solution
Why not: if we declare a box of bananas box of fruit, and put the Apple, he will cease to be a box of bananas.
#include <iostream>

Vocal class { // interface
public:
 virtual void shout() = 0;
 virtual ~Vocal() = default;
};

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

class Unrelated {};

// OPTION 1. Method of arm-twisting.

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]) {
 // Stupid proof of concept, waiting for C++20
 static_assert (std::is_base_of<Vocal, T>(), "Need array of Vocal");
 T** xx = x;
 shoutAll_v1(reinterpret_cast<Vocal**>(xx), N);
}

// OPTION 2. Virtual polymorphism.

class Choir { // interface
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>
VocalArray class : 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); does not compile

 std::cout << "V2" << std::endl;
shoutAll_v2(VocalArray<Dog>(sons));
 //shoutAll_v2(VocalArray<Unrelated>(unrel)); does not compile

 return 0;
}
Thanks, will definitely keep this code :)
I even suggested to use a reinterpret_cast(arr) - stephany.Flatley98 commented on April 4th 20 at 00:46
@stephany.Flatley98, It is a version 1 — only I added a proof of concept, not to compile if the array is incorrect. - Trycia.Mayer commented on April 4th 20 at 00:49
@Trycia.Mayer, Yes, exactly - thanks, missed the first because of the words arm-twisting :D - stephany.Flatley98 commented on April 4th 20 at 00:52
@stephany.Flatley98, @Trycia.Mayer, it is not necessary to use reinterpret_cast. It shot itself in the foot.
reinterpret_castworks is very insidious:
Unlike static_cast, but like const_cast, the reinterpret_cast expression does not compile to any CPU instructions... It is purely a compile-time directive which instructs the compiler to treat expression as if it had the type new_type.


Now, if your type is polymorphic, especially when multiple or virtual inheritance, you're in this place get remapping memory, the violation of the invariant, about a virtual table and a whole bunch of cockroaches that scatter throughout process memory, where the negligent performance of such a machine of death just able to reach.
static_cast - this here enough for the job. This caste will lead this to the correct pointer to the parent object type. - Sammy.OKeefe commented on April 4th 20 at 00:55

Find more questions by tags OOPC++