Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]


Groups > comp.lang.c++ > #83973

Re: Virtual base constructor arguments and constructor delegation

From "Alf P. Steinbach" <alf.p.steinbach@gmail.com>
Newsgroups comp.lang.c++
Subject Re: Virtual base constructor arguments and constructor delegation
Date 2022-05-07 14:25 +0200
Organization A noiseless patient Spider
Message-ID <t55oga$uou$1@dont-email.me> (permalink)
References <t55kt8$qn8s$1@gwaiyur.mb-net.net>

Show all headers | View raw


On 7 May 2022 13:24, Marcel Mueller wrote:
> Assuming the following class tree, the classic diamond but with all 
> classes without a standard constructor:
> 
> class Interpolation
> {public:
>    Interpolation(int count);
>    // ...
> }
> 
> class PolarInterpolation : public virtual Interpolation
> {public:
>    PolarInterpolation(int count) : Interpolation(2*count) {}
>    // ...
> }
> 
> class FileInterpolation : protected virtual Interpolation
> {public:
>    FileInterpolation(const char* filename, int count)
>    : Interpolation(count)
>    { // ...
>    }
> }
> 
> class PolarFileInterpolation
> : public FileInterpolation, protected PolarInterpolation
> {public:
>    PolarFileInterpolation(const char* filename, int count)
>    : Interpolation(2*count)
>    , FileInterpolation(filename, 0) // unused parameter count
>    , PolarInterpolation(0) // unused parameter count
>    {}
> }
> 

Strange use of `public` and `protected`, where from a client code of 
view a `PolarFileInterpolation` is not an `Interpolation`. Huh.


> The constructor of PolarFileInterpolation supplies count for all 3 base 
> constructors but this is pointless except for the first call to the 
> virtual base.
> While most compiler likely eliminate the nonsense parameters at runtime 
> they look strange in the code. Furthermore it might not be that easy to 
> get nonsense values for e.g. reference types.
> 
> To come around this one could add an additional constructor overload to 
> the base classes that do not initialize the virtual base. But there are 
> some drawbacks:
> - 1st it is impossible to define an "abstract" constructor that is 
> intended for sub classes only and only initializes the current class 
> without adding a default constructor to the virtual base class that will 
> never be called.

While the details you sketch may be impossible the general idea is not 
impossible.


> - 2nd the additional default constructor in the virtual base may 
> introduce errors when a derived class misses to invoke the "real" 
> constructor.
> - 3rd the (maybe complex) constructor of the derived classes need to be 
> implemented twice in this case. Constructor forwarding does not work 
> together with different constructors of the virtual base, although one 
> of them will never be called.
> 
> class FileInterpolation : protected virtual Interpolation
> {protected:
>    FileInterpolation(const char* filename); // init this class onlyy
>   public:
>    FileInterpolation(const char* filename, int count)
>    : Interpolation(count)
>    , FileInterpolation(filename) // does not work
>    {}
> }
> 
> Is there a smarter solution?
> 
> (Standard is C++11 for now)

Just the idea you sketched of dummy initialization, but with slightly 
different details:


#include <tuple>
using   std::ignore;

using C_str = const char*;

class Interpolation
{
protected:
     struct Dummy_init {};
     Interpolation( Dummy_init ) { throw 666; }

public:
     Interpolation( const int count ) { ignore = count; }
};

class Abstract_polar_interpolation:
     public virtual Interpolation
{
protected:
     Abstract_polar_interpolation():
         Interpolation( Dummy_init() )
     {}
};

class Polar_interpolation final:
     public virtual Abstract_polar_interpolation
{
public:
     Polar_interpolation( const int count ):
         Interpolation( 2*count ),
         Abstract_polar_interpolation()
     {}
};

class Abstract_file_interpolation:
     public virtual Interpolation
{
protected:
     Abstract_file_interpolation( const C_str filename ):
         Interpolation( Dummy_init() )   // Isn't actually called.
     { ignore = filename; }
};

class File_interpolation final:
     public Abstract_file_interpolation
{
public:
     File_interpolation( const C_str filename, const int count ):
         Interpolation(count),
         Abstract_file_interpolation( filename )
     { ignore = filename; }
};

class Polar_file_interpolation final:
     public Abstract_file_interpolation,
     public Abstract_polar_interpolation
{
public:
     Polar_file_interpolation( const C_str filename, const int count ):
         Interpolation( 2*count ),
         Abstract_file_interpolation( filename ),
         Abstract_polar_interpolation()
     {}
};

auto main() -> int
{
     auto    pi  = Polar_interpolation( 123 );
     auto    fi  = File_interpolation( "balthazar", 99 );
     auto    pfi = Polar_file_interpolation( "pfi", -1 );

     (void) pi; (void) fi; (void) pfi;
}


Cheers,

- Alf

Back to comp.lang.c++ | Previous | NextPrevious in thread | Next in thread | Find similar | Unroll thread


Thread

Virtual base constructor arguments and constructor delegation Marcel Mueller <news.5.maazl@spamgourmet.org> - 2022-05-07 13:24 +0200
  Re: Virtual base constructor arguments and constructor delegation "Alf P. Steinbach" <alf.p.steinbach@gmail.com> - 2022-05-07 14:25 +0200
    Re: Virtual base constructor arguments and constructor delegation Marcel Mueller <news.5.maazl@spamgourmet.org> - 2022-05-08 11:45 +0200
      Re: Virtual base constructor arguments and constructor delegation Manfred <noname@add.invalid> - 2022-05-08 18:56 +0200
        Re: Virtual base constructor arguments and constructor delegation "Alf P. Steinbach" <alf.p.steinbach@gmail.com> - 2022-05-09 00:18 +0200
          Re: Virtual base constructor arguments and constructor delegation Manfred <noname@add.invalid> - 2022-05-09 14:56 +0200
  Re: Virtual base constructor arguments and constructor delegation Sam <sam@email-scan.com> - 2022-05-08 09:34 -0400

csiph-web