Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]
Groups > comp.lang.c++ > #83973
| 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> |
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 | Next — Previous in thread | Next in thread | Find similar | Unroll 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