You probably shouldn't be (ab)using inheritance...
Question: why do you use inheritance for bisArray<T>
?
Is it to add extra functionality to array_dyn<T>
that can entirely be written in the public interface of array_dyn<T>
? In that case, add non-member functions to provide that functionality instead of inheriting and adding member functions. So instead of
template<class T>
class bisArray: public array_dyn<T>
{
public:
void doCoolStuffThatBoostDoesNotProvide() const;
};
write a non-member function
template<class T>
void doCoolStuffThatBoostDoesNotProvide(array_dyn<T> const& s);
If you need to add functionality that requires extra state to a array_dyn<T>
, use composition
template<class T>
class bisArray
{
public:
void doCoolStuffThatBoostCannotImplement() const;
private:
some_fancy_type s_;
array_dyn<T> a_;
};
array_dyn<T>
was never designed to be a base class. For one, it doesn't have a virtual destructor. Second, the designers of array_dyn<T>
also composed a std::vector<T>
, and did not inherit from it, for exactly those reasons.
Of course, when using composition, bisArray<T>
will have to redefine the entire interface (members and constructors) that it wants to keep. However, in the words of Alexandrescu and Sutter:
Admittedly, it's tedious to have to write passthrough functions for
the member functions you want to keep, but such an implementation is
vastly better and safer than using public or nonpublic inheritance.
... but use the base constructors if you do...
OK, you absolutely-positively-definitely want to use inheritance. Well that's easy: just delegate all work to the array_dyn<T>
base class constructor:
template
< typename Sizes
>
array_dyn( dirs a_dir, Sizes const& a_sizes={})
: super_t( a_dir, a_sizes)
, my_data( super_t::size())
{
}
Your two requested constructors can then be gotten from your current version minus the initialization of my_data
because the array_dyn<T>
constructor already does the exact same amount of work
// note use explicit keyword for single-argument constructors
template<typename Sizes>
explicit bisArray( dirs a_dir, Sizes const& a_sizes={} )
: super_type(a_dir, a_sizes)
{}
template < typename Sizes >
bisArray( Sizes const& a_sizes={} )
: super_type(dir_fwd, a_sizes)
{}
In case you want to set super_type::my_data
to another value than what the super_type
constructor does, just put such a statement in the body of the constructor. But from the Boost code and your code alone that doesn't seem to be required here.
... or use factory functions to get the best of both worlds
Still, if all that bisArray<T>
does is create a default constructor that takes the C-array style parameter dir_fwd
, why not drop the inheritance, and write two non-member factory functions that return a array_dyn<T>
with the corresponding constructor arguments
template<typename T, typename Sizes>
make_fortran_array_dyn(Sizes const& a_sizes={} )
{
return array_dyn<T>(dir_rev, a_sizes);
}
template <typename T, typename Sizes >
make_c_array_dyn( Sizes const& a_sizes={} )
{
return array_dyn<T>(dir_fwd, a_sizes);
}
which you can call like this:
auto c = make_c_array_dyn<double>(your_sizes);
auto f = make_fortran_array_dyn<double>(your_sizes);