Derived Class Constructors

N

nozyrev

Hi,
I apologize in advance if this is a very dumb question. I've been
struggling with this problem for some time: I have an abstract base
class called Base and n derived classes D1, D2, ....Dn. I would like
to have a constructor for each derived class that takes any of the
other derived classes as an argument so that these statements are
valid:

D1 d1;
D2 d2;

D3 d3a(d1);
D3 d3b(d2);

What is the syntax that I have to use for those statements to compile.
I realize that, for any given derived class i, I can't use Di (const
Base& b) as the constructor. Do i need to use virtual constructors? If
so, how?

Thanks for your help
 
A

Alf P. Steinbach

* nozyrev:
Hi,
I apologize in advance if this is a very dumb question.

Dumb questions are good, too clever wrong questions are ungood.

I've been
struggling with this problem for some time: I have an abstract base
class called Base and n derived classes D1, D2, ....Dn. I would like
to have a constructor for each derived class that takes any of the
other derived classes as an argument so that these statements are
valid:

D1 d1;
D2 d2;

D3 d3a(d1);
D3 d3b(d2);

What is the syntax that I have to use for those statements to compile.
I realize that, for any given derived class i, I can't use Di (const
Base& b) as the constructor.

Since that's the most obvious solution, why can't you?

Do i need to use virtual constructors?

No.

You need to define what these conversions should mean, and whether you
have an open-ended set of derived classes.
 
S

Salt_Peter

Hi,
I apologize in advance if this is a very dumb question. I've been
struggling with this problem for some time: I have an abstract base
class called Base and n derived classes D1, D2, ....Dn. I would like
to have a constructor for each derived class that takes any of the
other derived classes as an argument so that these statements are
valid:

D1 d1;
D2 d2;

D3 d3a(d1);
D3 d3b(d2);

What is the syntax that I have to use for those statements to compile.
I realize that, for any given derived class i, I can't use Di (const
Base& b) as the constructor. Do i need to use virtual constructors? If
so, how?

Thanks for your help

Constructors initialize instances of a type. The 'relationship'
between the types is what governs how the system should be designed.
One does not ask "how can i make the above statements compile?" since
we don't know what the relationship is/are between D1 and D2, D1 and
D3 and the same goes with types D2 and D3, etc

For all we know D3 might be composed of a D1 member and derived from
type D2. Or the other way around. Maybe both D1 and D2 are members of
D3? D3 is derived from both D1 and D2? Perhaps D3 is derived from D2;
which is derived from D1; which is derived from Base?
 
G

Greg Herlihy

I apologize in advance if this is a very dumb question. I've been
struggling with this problem for some time: I have an abstract base
class called Base and n derived classes D1, D2, ....Dn. I would like
to have a constructor for each derived class that takes any of the
other derived classes as an argument so that these statements are
valid:

D1 d1;
D2 d2;

D3 d3a(d1);
D3 d3b(d2);

What is the syntax that I have to use for those statements to compile.
I realize that, for any given derived class i, I can't use Di (const
Base& b) as the constructor. Do i need to use virtual constructors? If
so, how?

No, but a class template and some typedefs might help. Something along the
lines of:

class Base
{
public:
virtual ~Base() {}
virtual void f() = 0;
};

template <int I>
class D : public Base
{
public:
D() {}
D(const D& d ) {}

template <int I2>
D(const D<I2>& d) {}

// to do: add operator=

void f() {}
};

typedef D<1> D1;
typedef D<2> D2;
typedef D<3> D3;

int main()
{
D1 d1;
D2 d2;

D3 d3a(d1);
D3 d3b(d2);
}

Greg
 
J

James Kanze

I apologize in advance if this is a very dumb question. I've been
struggling with this problem for some time: I have an abstract base
class called Base and n derived classes D1, D2, ....Dn. I would like
to have a constructor for each derived class that takes any of the
other derived classes as an argument so that these statements are
valid:
D1 d1;
D2 d2;
D3 d3a(d1);
D3 d3b(d2);
What is the syntax that I have to use for those statements to compile.
I realize that, for any given derived class i, I can't use Di (const
Base& b) as the constructor.

You can, at least as far as the language rules are concerned.
Do i need to use virtual constructors?

There's no such thing.

The real problem isn't syntax: a constructor taking a reference
to the base class, or a templated constructor, both solve that
problem. The real problem is semantics. What does it mean to
construct a D3 object from a D2 or a D1? What happens to
information that is in D2 or D1, but isn't present in D3? How
do you initialize information that is present in a D3, but not
in a D1 or a D2? If all relevant information is present in the
base, and the derived classes just provide different means of
manipulating this information, a constructor from Base const& is
the obvious answer. If the necessary information is in the
derived class, but there are "standard" ways of accessing it,
and it is always present (or there is an appropriate default if
it isn't present), then a templated constructor is a solution.
If each pair Dn->Dm has distinctive semantics, there's not much
you can do but write n different constructors for each Dm.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
474,262
Messages
2,571,056
Members
48,769
Latest member
Clifft

Latest Threads

Top