Topic: Virtual Base Constructors
Author: greg.hickman@lmco.com ("Hickman, Greg")
Date: Fri, 21 Feb 2003 02:56:13 +0000 (UTC) Raw View
If a compiler can ascertain that a class with a virtual base isn't
instantiable, wouldn't it be possible to allow that class to omit calling
the constructor of the virtual base since it will have to be called by a
more derived class anyway?
For example,
class Io_object {
public:
virtual ~Io_object() {}
virtual void read_from(const Io_reader&) = 0;
virtual void write_to(const Io_writer&) const = 0;
protected:
Io_object(const Io_type&);
};
class Base : public virtual Io_object {
public:
void foo() = 0;
protected:
Base(const Io_type& type) : Io_object(type) {}
};
class Concrete : public Base {
};
Do we really have to require that Base call the Io_object constructor even
though it ultimately *has* to be handled by the Concrete type anyway?
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html ]
Author: francis.glassborow@ntlworld.com (Francis Glassborow)
Date: Fri, 21 Feb 2003 16:44:08 +0000 (UTC) Raw View
In article
<58F604E3D17AD4119D8600508BE325060EA9A2F1@emss07m04.lmtas.lmco.com>,
"Hickman, Greg" <greg.hickman@lmco.com> writes
>If a compiler can ascertain that a class with a virtual base isn't
>instantiable, wouldn't it be possible to allow that class to omit calling
>the constructor of the virtual base since it will have to be called by a
>more derived class anyway?
>
>For example,
>
>class Io_object {
>public:
> virtual ~Io_object() {}
> virtual void read_from(const Io_reader&) = 0;
> virtual void write_to(const Io_writer&) const = 0;
>protected:
> Io_object(const Io_type&);
As this is already an ABC what is this for in a stateless class.
>};
>
>class Base : public virtual Io_object {
>public:
> void foo() = 0;
>protected:
> Base(const Io_type& type) : Io_object(type) {}
Why are you explicitly calling a ctor for a stateless base class?
>};
>
>class Concrete : public Base {
>};
>
>Do we really have to require that Base call the Io_object constructor even
>though it ultimately *has* to be handled by the Concrete type anyway?
Please give an example where the required base ctor would not be
compiler generated.
--
ACCU Spring Conference 2003 April 2-5
The Conference you cannot afford to miss
Check the details: http://www.accuconference.co.uk/
Francis Glassborow ACCU
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html ]
Author: hyrosen@mail.com (Hyman Rosen)
Date: Fri, 21 Feb 2003 16:44:14 +0000 (UTC) Raw View
Hickman, Greg wrote:
> Do we really have to require that Base call the Io_object constructor even
> though it ultimately *has* to be handled by the Concrete type anyway?
No, quite the opposite. Base is required *not* to call the
Io_object constructor when Concrete is being constructed.
Despite appearances, a virtual base class is constructed
only once, from the most derived class.
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html ]
Author: philippe_mori@hotmail.com ("Philippe Mori")
Date: Fri, 21 Feb 2003 20:34:30 +0000 (UTC) Raw View
> If a compiler can ascertain that a class with a virtual base isn't
> instantiable, wouldn't it be possible to allow that class to omit calling
> the constructor of the virtual base since it will have to be called by a
> more derived class anyway?
>
> For example,
>
> class Io_object {
> public:
> virtual ~Io_object() {}
> virtual void read_from(const Io_reader&) = 0;
> virtual void write_to(const Io_writer&) const = 0;
> protected:
> Io_object(const Io_type&);
> };
>
> class Base : public virtual Io_object {
> public:
> void foo() = 0;
> protected:
> Base(const Io_type& type) : Io_object(type) {}
> };
>
> class Concrete : public Base {
> };
>
> Do we really have to require that Base call the Io_object constructor even
> though it ultimately *has* to be handled by the Concrete type anyway?
>
Since you must currently calls Io_object from Concrete constructor (because
there are not default constructor in Io_Object) and you never create Base
object, I think that the compiler should allows that the constructor of a
virtual
base is not called from an intermediate class like Base.
If the user try to create an object of such a type, then it should be an
error
but otherwise, IMHO the compiler should ignore it (it should essentially
be considered as an abstract class if the class cannot be constructed
because a virtual base does not have default constructor and the
intermediate class (Base in exambple above) does not call it.
OTOH, I think that rules should be changed so that it will be possible to
call a virtual base constructor from an intermediate class and do not
specify it in the concrete type. The rule should be that the most derived
call to the virtual base constructor explicitly specified should be used
(default could be forced by calling a constructor with an empty argument
list).
Here some samples:
class VBase {
public:
VBase(int);
// VBase();
};
class Base : public VBase {
public:
Base() : VBase(25) {}
Base(int i) : VBase(i) {}
// Does not compile if VBase is not un-commented
Base(double d) : VBase() {}
};
class Der : public Base {
public:
Der(int i) : Base(i) {} // #1
Der(int i, int j) : VBase(j), Base(i) { } // #2
Der() {} // #3
Der(double d) : Base(d) {} // #4
};
#1 would calls VBase(i) --- even if VBase() is un-commented
#2 would calls VBase(j) --- as this is the case now
#3 would calls VBase(25) --- even if VBase() is un-commented
#4 would not compile. If VBase() is uncommented, calls it.
So essentially, starting from the most derived class, we uses the
first usable explicit call. If there is an ambiguity, an error occurs
except if the default constructor of VBase for the for the most
derived class (or a parent at a level where there are no ambiguity ---
that rule would be used if an intermediate class is a friend of the
virtual class).
Or he we want better backward compatibility, we may eventually
uses that extension only when there are no default constructor and
the most concrete type does not explicitly call it.
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html ]
Author: greg.hickman@lmco.com (Greg Hickman)
Date: Fri, 21 Feb 2003 22:00:36 +0000 (UTC) Raw View
"Francis Glassborow" <francis.glassborow@ntlworld.com> wrote in message
news:1trs9ECfMhV+Ew9M@robinton.demon.co.uk...
> In article
> <58F604E3D17AD4119D8600508BE325060EA9A2F1@emss07m04.lmtas.lmco.com>,
> "Hickman, Greg" <greg.hickman@lmco.com> writes
> >If a compiler can ascertain that a class with a virtual base isn't
> >instantiable, wouldn't it be possible to allow that class to omit calling
> >the constructor of the virtual base since it will have to be called by a
> >more derived class anyway?
> >
> >For example,
> >
> >class Io_object {
> >public:
> > virtual ~Io_object() {}
> > virtual void read_from(const Io_reader&) = 0;
> > virtual void write_to(const Io_writer&) const = 0;
> >protected:
> > Io_object(const Io_type&);
>
> As this is already an ABC what is this for in a stateless class.
Sorry, I engaged in a little too much eliding, as it were. I meant to imply
(psychic-ly) by the presence of the constructor that the base did in fact
have some data. For example,
class Io_type {
public:
explicit Io_type(const char* name) : name_(name) {}
//...
private:
const char* name_;
};
class Io_object {
public:
// ...
protected:
Io_object(const Io_type& type) : type_(type) {}
private:
Io_type type_;
};
class Base : public virtual Io_object { // this is abstract
public:
//...
protected:
Base(const Io_type& type) : Io_object(type) {}
};
class Concrete : public Base {
public:
Concrete();
//...
private:
static const Io_type type_;
};
Concrete::Concrete() : Io_object(type_), Base(type) { }
It seems superfluous for Base to supply a call to the Io_object constructor
since Base has to be derived from before it can be instantiated, and it's
the most derived class that will ultimately have to call the constructor for
the Io_object virtual base anyway.
Greg
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html ]
Author: greg.hickman@lmco.com (Greg Hickman)
Date: Fri, 21 Feb 2003 22:13:08 +0000 (UTC) Raw View
"Hyman Rosen" <hyrosen@mail.com> wrote in message
news:1045838077.814275@master.nyc.kbcfp.com...
> Hickman, Greg wrote:
> > Do we really have to require that Base call the Io_object constructor
even
> > though it ultimately *has* to be handled by the Concrete type anyway?
>
> No, quite the opposite. Base is required *not* to call the
> Io_object constructor when Concrete is being constructed.
> Despite appearances, a virtual base class is constructed
> only once, from the most derived class.
But the compiler requires that each intermediate base between the virtual
base and the most derived class repeat the constructor call in its member
initialization list, even though only the call from the most derived class
will ultimately be invoked. If the intermediate bases are abstract, why not
allow them to the omit superfluous syntax for calls that will never be
invoked?
Greg
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html ]