Constructor Filter Through... ?

J

JKop

You know the whole "Linked List" concept, where each object knows where the
the next one is. Well, in one of its simplest forms I have:

template<class T>
struct LinkedObject : virtual public T
{
LinkedObject* p_next;
};


The only problem here is in calling the constructor:


#include <string>

int main()
{
LinkedObject<std::string> blah("Monkey!");

blah.p_next = new LinkedObject<std::string>("Ape!");


delete blah.p_next;
}


Is there any way to achieve something akin to the above, whereby the call to
the derived class's constructor "filters through" to the base class's
constructor... ?

What I'm trying to achieve is that an object of type "LinkedObject
<std::string>" will behave exactly as would an object of type
"std::string" - the only difference being that you can do:

blah.p_next = 0;


As such, I want the call to the constructor of "LinkedObject<T>" to fall
through to the constructor of the base class.


-JKop
 
J

John Harrison

JKop said:
You know the whole "Linked List" concept, where each object knows where the
the next one is. Well, in one of its simplest forms I have:

template<class T>
struct LinkedObject : virtual public T
{
LinkedObject* p_next;
};


The only problem here is in calling the constructor:


#include <string>

int main()
{
LinkedObject<std::string> blah("Monkey!");

blah.p_next = new LinkedObject<std::string>("Ape!");


delete blah.p_next;
}


Is there any way to achieve something akin to the above, whereby the call to
the derived class's constructor "filters through" to the base class's
constructor... ?

What I'm trying to achieve is that an object of type "LinkedObject
<std::string>" will behave exactly as would an object of type
"std::string" - the only difference being that you can do:

blah.p_next = 0;


As such, I want the call to the constructor of "LinkedObject<T>" to fall
through to the constructor of the base class.


-JKop

You can add generic templated constructors to LinkedObject, like this

template<class T>
struct LinkedObject : virtual public T
{
LinkedObject() {}
template <class A> LinkedObject(const A& a) : T(a) {}
template <class A, class B> LinkedObject(const A& a, const B& b) : T(a,
b) {}
template <class A, class B, class C> LinkedObject(const A& a, const B&
b, const C& c) : T(a, b, c) {}
// etc etc, go as high as you like
LinkedObject* p_next;
};

This works because the constructor will only be instantiated if it is used.
Therefore its not a problem if T doesn't have all the constructors that
LinkedObject is assuming. Does need a default constructor however.

john
 
J

JKop

John Harrison posted:
You can add generic templated constructors to LinkedObject, like this

template<class T>
struct LinkedObject : virtual public T
{
LinkedObject() {}
template <class A> LinkedObject(const A& a) : T(a) {}
template <class A, class B> LinkedObject(const A& a, const B& b) :
T(a,
b) {}
template <class A, class B, class C> LinkedObject(const A& a,
const B&
b, const C& c) : T(a, b, c) {}
// etc etc, go as high as you like
LinkedObject* p_next;
};

This works because the constructor will only be instantiated if it is
used. Therefore its not a problem if T doesn't have all the
constructors that LinkedObject is assuming. Does need a default
constructor however.

john


Thanks.

But shouldn't the function arguments be *non*-const?, as in:


template <class A> LinkedObject(A& a) : T(a) {}

template <class A, class B> LinkedObject(A& a, B& b) : T(a,b) {}

template <class A, class B, class C> LinkedObject(A& a, B& b, C& c) : T(a,
b, c) {}


template <class A, class B, class C, class D> LinkedObject(A& a, B& b, C& c,
D& d) : T(a,b,c,d){}



This way, if the expressions supplied as arguments to the constructor are
actually const, then the argument types will automagically become const too.


Is there any potential pitfalls in this... I don't see any at the moment.


-JKop
 
J

John Harrison

JKop said:
John Harrison posted:



Thanks.

But shouldn't the function arguments be *non*-const?, as in:


template <class A> LinkedObject(A& a) : T(a) {}

template <class A, class B> LinkedObject(A& a, B& b) : T(a,b) {}

template <class A, class B, class C> LinkedObject(A& a, B& b, C& c) : T(a,
b, c) {}


template <class A, class B, class C, class D> LinkedObject(A& a, B& b, C& c,
D& d) : T(a,b,c,d){}



This way, if the expressions supplied as arguments to the constructor are
actually const, then the argument types will automagically become const too.


Is there any potential pitfalls in this... I don't see any at the moment.

But then you won't be able to call any of your constructors with a
temporary.

I was looking at some code that did this just the other day. I don't have
access to it right now but I think they used const references, but said
something like 'if you want non-const references use something like the
boost ref library'.

John
 

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

No members online now.

Forum statistics

Threads
473,768
Messages
2,569,574
Members
45,048
Latest member
verona

Latest Threads

Top