473,399 Members | 3,106 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,399 software developers and data experts.

class that have a member of type that's derived from it

Is there a way to properly do this?

struct Derived;

struct Base{
Derived der;
};

struct Derived: public Base{

};
Jul 21 '06 #1
9 1627
Mirko Puhic wrote:
Is there a way to properly do this?

struct Derived;

struct Base{
Derived der;
};

struct Derived: public Base{

};
This is called the Curiously Recurring Template Pattern (honestly).

template <typename DerivedType>
struct Base
{
DerivedType der ;
} ;

struct Derived : public Base<Derived>
{
} ;

--
Alan Johnson
Jul 21 '06 #2
Alan Johnson wrote:
Mirko Puhic wrote:
>Is there a way to properly do this?

struct Derived;

struct Base{
Derived der;
};

struct Derived: public Base{

};

This is called the Curiously Recurring Template Pattern (honestly).

template <typename DerivedType>
struct Base
{
DerivedType der ;
} ;

struct Derived : public Base<Derived>
{
} ;
Except, I should have run it through a compiler before posting. That
won't work. And object of type Derived can't contain a member (directly
or via inheritance) of type Derived, because that member would, of
course, also contain an member of type Derived, which would also ... you
see the problem.

What you CAN do is have a pointer or reference. Example:
struct Derived ;

template <typename DerivedType>
struct Base
{
DerivedType * der ;
} ;

struct Derived : public Base<Derived>
{
} ;

--
Alan Johnson

Jul 21 '06 #3
Alan Johnson wrote:
Alan Johnson wrote:
>Mirko Puhic wrote:
>>Is there a way to properly do this?

struct Derived;

struct Base{
Derived der;
};

struct Derived: public Base{

};

This is called the Curiously Recurring Template Pattern (honestly).

template <typename DerivedType>
struct Base
{
DerivedType der ;
} ;

struct Derived : public Base<Derived>
{
} ;

Except, I should have run it through a compiler before posting. That
won't work. And object of type Derived can't contain a member (directly
or via inheritance) of type Derived, because that member would, of
course, also contain an member of type Derived, which would also ... you
see the problem.

What you CAN do is have a pointer or reference. Example:
struct Derived ;

template <typename DerivedType>
struct Base
{
DerivedType * der ;
} ;

struct Derived : public Base<Derived>
{
} ;
I see. Pointer will do. But in that case I think there's no need to use
a template:
struct Derived;

struct Base{

Derived * der;

};

struct Derived: public Base{

};
Jul 21 '06 #4
Mirko Puhic wrote:
Alan Johnson wrote:
>Alan Johnson wrote:
>>Mirko Puhic wrote:
Is there a way to properly do this?

struct Derived;

struct Base{
Derived der;
};

struct Derived: public Base{

};

This is called the Curiously Recurring Template Pattern (honestly).

template <typename DerivedType>
struct Base
{
DerivedType der ;
} ;

struct Derived : public Base<Derived>
{
} ;

Except, I should have run it through a compiler before posting. That
won't work. And object of type Derived can't contain a member
(directly or via inheritance) of type Derived, because that member
would, of course, also contain an member of type Derived, which would
also ... you see the problem.

What you CAN do is have a pointer or reference. Example:
struct Derived ;

template <typename DerivedType>
struct Base
{
DerivedType * der ;
} ;

struct Derived : public Base<Derived>
{
} ;

I see. Pointer will do. But in that case I think there's no need to use
a template:
struct Derived;

struct Base{

Derived * der;

};

struct Derived: public Base{

};
True, though there are still times when that template pattern is useful.
Consider if you wanted to make a utility from which people could
derive to make their class into a linked list node. It might be useful
to do something like:

template <typename T>
struct Linkable
{
T * next ;
} ;

class MyType : public Linkable<MyType>
{
// ...
} ;

Another case is when you need each derived type to have its own copy of
static members.

template <typename T>
struct Base
{
// Note that this class doesn't actually use its template parameter.
static SomeType value ;
} ;

// A::value and B::value are separate objects.
class A : public Base<A{}
class B : public Base<B{}
More exotic uses arise in various template metaprogramming techniques.

--
Alan Johnson
Jul 21 '06 #5
Alan Johnson wrote:
Mirko Puhic wrote:
>Alan Johnson wrote:
>>Alan Johnson wrote:
Mirko Puhic wrote:
Is there a way to properly do this?
>
>
>
struct Derived;
>
struct Base{
Derived der;
};
>
struct Derived: public Base{
>
};

This is called the Curiously Recurring Template Pattern (honestly).

template <typename DerivedType>
struct Base
{
DerivedType der ;
} ;

struct Derived : public Base<Derived>
{
} ;
Except, I should have run it through a compiler before posting. That
won't work. And object of type Derived can't contain a member
(directly or via inheritance) of type Derived, because that member
would, of course, also contain an member of type Derived, which would
also ... you see the problem.

What you CAN do is have a pointer or reference. Example:
struct Derived ;

template <typename DerivedType>
struct Base
{
DerivedType * der ;
} ;

struct Derived : public Base<Derived>
{
} ;

I see. Pointer will do. But in that case I think there's no need to
use a template:
struct Derived;

struct Base{

Derived * der;
};

struct Derived: public Base{
};

True, though there are still times when that template pattern is useful.
Consider if you wanted to make a utility from which people could derive
to make their class into a linked list node. It might be useful to do
something like:

template <typename T>
struct Linkable
{
T * next ;
} ;

class MyType : public Linkable<MyType>
{
// ...
} ;

Another case is when you need each derived type to have its own copy of
static members.

template <typename T>
struct Base
{
// Note that this class doesn't actually use its template parameter.
static SomeType value ;
} ;

// A::value and B::value are separate objects.
class A : public Base<A{}
class B : public Base<B{}
More exotic uses arise in various template metaprogramming techniques.
Thenks, having a separate static member for each derived class seems
really useful.
Only problem with using pointer is that you can't create actual object
in the constructor because it would send the program into infinite
recursion.
Jul 21 '06 #6

Mirko Puhic wrote:
Thenks, having a separate static member for each derived class seems
really useful.
Only problem with using pointer is that you can't create actual object
in the constructor because it would send the program into infinite
recursion.
You don't even need the seperate member in the base using CRTP. You
already have the implicit this pointer that can be casted to the
derived.

template <class DerivedT>
struct Base
{
void foo()
{
dynamic_cast<Derived*>(this)->doFoo();
}
};

class Derived : public Base<Derived>
{
public:
void doFoo(){}
};

I still can't see how you can get recursion... elaborate please.

Regards,

W

Jul 21 '06 #7
werasm wrote:
>
I still can't see how you can get recursion... elaborate please.
In case I want Derived object to be created in Base constructor:
class Derived;

class Base{
public:
Base(){
der = new Derived();
}
Derived * der;

};

class Derived: public Base{

}
Jul 21 '06 #8
Mirko Puhic wrote:
werasm wrote:
>>
I still can't see how you can get recursion... elaborate please.

In case I want Derived object to be created in Base constructor:
class Derived;

class Base{
public:
Base(){
der = new Derived();
}
Derived * der;

};

class Derived: public Base{

}
I mean it's the same "recursion" problem as with using the type Derived
as an actual member (not pointer) of the class Base.
Jul 21 '06 #9

Mirko Puhic wrote:
In case I want Derived object to be created in Base constructor:
Why would you want do to that? Base can only be constructed upon
instantiating derived anyway....

Derived d;//...

constructs base implicitly, and the pointer in base becomes a valid
derived...

template <class DerivedT>
struct Base
{
Derived* getDerived(){ return dynamic_cast<DerivedT*>(this); }
};

class Derived : public Base<Derived>{ /*...*/ };

Derived::Derived
: Base<Derived>()
{
//From this point onwards, we can no obtain valid derived pointer...
}

int main()
{
Derived d;
Base<Derived>* pb( &d );
pb->getDerived()->foo();//would work assuming Derived had member
function foo...

return 0;
}
class Derived;

class Base{
public:
Base(){
der = new Derived();
}
Derived * der;

};
You don't need to assign a new Derived to der, you don't even need a
der as this is implicitly already a pointer to the derived class if you
cast it, provided Derived is truly inherited from Base (which one can
enforce, btw).

Kind regards,

Werner

Jul 21 '06 #10

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

2
by: Michael Young | last post by:
I've been trying to compile code similar to the example code below, but I keep getting errors indicating that the function 'foo()' is not accessible. At first, I thought this was a bug in the...
5
by: kuvpatel | last post by:
Hi I want to refer a class called LogEvent, and use one of its methods called WriteMessage without actually having to create an instance of Logevent. I have tried using the word sealed with...
5
by: Andy | last post by:
Hi all, I have a site with the following architecture: Common.Web.dll - Contains a CommonPageBase class which inherits System.Web.UI.Page myadd.dll - Contains PageBase which inherits...
9
by: olanglois | last post by:
Hi, I am not sure if I have found a compiler bug (I am using VC++.NET2003) or if this is the correct behavior defined by the language but I am sure someone can clear up my confusion. Suppose the...
14
by: Dave Booker | last post by:
It looks like the language is trying to prevent me from doing this sort of thing. Nevertheless, the following compiles, and I'd like to know why it doesn't work the way it should: public class...
15
by: Bob Johnson | last post by:
I have a base class that must have a member variable populated by, and only by, derived classes. It appears that if I declare the variable as "internal protected" then the base class *can*...
15
by: =?Utf-8?B?R2Vvcmdl?= | last post by:
Hello everyone, I met with a strange issue that derived class function can not access base class's protected member. Do you know why? Here is the error message and code. error C2248:...
3
by: Immortal Nephi | last post by:
The rule of inheritance states that you define from top to bottom. Sometimes, you want to define base class and set reference from dervied class to base class, but you violate the rule. Here is an...
19
by: Juha Nieminen | last post by:
Assume I have a class Base, and then this: struct Derived: public Base { AnotherClass member; }; Also assume that I'm allocating an object of type 'Derived' with a custom allocator and...
0
by: emmanuelkatto | last post by:
Hi All, I am Emmanuel katto from Uganda. I want to ask what challenges you've faced while migrating a website to cloud. Please let me know. Thanks! Emmanuel
0
BarryA
by: BarryA | last post by:
What are the essential steps and strategies outlined in the Data Structures and Algorithms (DSA) roadmap for aspiring data scientists? How can individuals effectively utilize this roadmap to progress...
1
by: nemocccc | last post by:
hello, everyone, I want to develop a software for my android phone for daily needs, any suggestions?
0
marktang
by: marktang | last post by:
ONU (Optical Network Unit) is one of the key components for providing high-speed Internet services. Its primary function is to act as an endpoint device located at the user's premises. However,...
0
by: Hystou | last post by:
Most computers default to English, but sometimes we require a different language, especially when relocating. Forgot to request a specific language before your computer shipped? No problem! You can...
0
jinu1996
by: jinu1996 | last post by:
In today's digital age, having a compelling online presence is paramount for businesses aiming to thrive in a competitive landscape. At the heart of this digital strategy lies an intricately woven...
0
by: Hystou | last post by:
Overview: Windows 11 and 10 have less user interface control over operating system update behaviour than previous versions of Windows. In Windows 11 and 10, there is no way to turn off the Windows...
0
agi2029
by: agi2029 | last post by:
Let's talk about the concept of autonomous AI software engineers and no-code agents. These AIs are designed to manage the entire lifecycle of a software development project—planning, coding, testing,...
0
isladogs
by: isladogs | last post by:
The next Access Europe User Group meeting will be on Wednesday 1 May 2024 starting at 18:00 UK time (6PM UTC+1) and finishing by 19:30 (7.30PM). In this session, we are pleased to welcome a new...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.