#include <iostream>
template <typename T>
class Base
{
public:
virtual T* foo(T* a)=0;
class NestedBase
{
public:
NestedBase(T* pData);
~NestedBase(){delete data;}
//protected:
T* data;
};
Base(T* pData=0){pNBdata = new NestedBase(pData);}
~Base(){delete pNBdata; pNBdata=0;}
protected:
NestedBase* pNBdata;
};
template <typename T>
Base<T>::NestedBase::NestedBase(T* pData)
{
data = pData;
T* foo(data); // this line does not work, but I want it to call derived foo from nested base class
}
template <typename T>
class Derived: public Base<T>
{
public:
Derived(T& rData):Base<T>(&rData){}
T* foo(T* a);
};
template <typename T>
T* Derived<T>::foo(T* a)
{
std::cout<<"Did something"<<std::endl;
return a;
}
int main()
{
int x = 5;
int y = 10;
Derived<int>* pDeriv = new Derived<int>(x);
return 0;
}
Calling virtual functions from nested base classes?
I'm trying to get the following to work but I cannot... the summary is that I have a base class that contains a nested class. The base class is a manager class for its nested class. I want to derive different instances of the manager class and each of these instances cause the nested base class instance to be constructed differently. Thus, I *think* the way I want to solve this problem is to call a virtual member function from within the nested base class constructor. However, this does not work, as the following example shows (compiles with MSVC 7.1)
How can I call the derived version of foo from within the nested base class? If this is not possible, what other way can I force different constructor behaviour on the nested base class from a derived class?
Any and all help is appreciated.
Thanks,
Timkin
Your constructor for NestedBase would have to look something like this:
But this won't work anyway since the NestedBase instance is being created in the constructor of Base, that is before Derived has been constructed (and more importantly its vtable entries). You'll have to work out an approach to achieve what you need by either calling an Init() function after the object is constructed or instantiate the NestedBase instance in the constructor of every derived class.
template <typename T>Base<T>::NestedBase::NestedBase(T* pData, Base base){ data = pData; base->foo(data);}
But this won't work anyway since the NestedBase instance is being created in the constructor of Base, that is before Derived has been constructed (and more importantly its vtable entries). You'll have to work out an approach to achieve what you need by either calling an Init() function after the object is constructed or instantiate the NestedBase instance in the constructor of every derived class.
wow.. That's some confusing code and I have no idea why you are wanting to do this stuff(so you may want to rethink what you are doing and see if there is a simplier way) but anyways that isn't the issue here....
If I understand your code correctly, in order to call Base::Foo from the NestedBase class. This is required:
a-) NestedBase doesn't have a pointer or anything to the Base class(or derivative) just the pointer to the data.
b-) If you gave the NestedBase class a pointer to the Base class(like passing the this pointer). You could store it and do it that way AFTER all the constructors are called. The way your code is setup now the constructor order would be like this:
Base's Constructor
NestedBase's Constructor
Derived's Constructor
AFAIK Virtual Methods won't/shouldn't work until all the constructors are called so you could called Foo until after the constructors were called.
If I understand your code correctly, in order to call Base::Foo from the NestedBase class. This is required:
a-) NestedBase doesn't have a pointer or anything to the Base class(or derivative) just the pointer to the data.
b-) If you gave the NestedBase class a pointer to the Base class(like passing the this pointer). You could store it and do it that way AFTER all the constructors are called. The way your code is setup now the constructor order would be like this:
Base's Constructor
NestedBase's Constructor
Derived's Constructor
AFAIK Virtual Methods won't/shouldn't work until all the constructors are called so you could called Foo until after the constructors were called.
Ah... of course... I hadn't considered construction order. Thanks guys.
To answer the: 'why am I doing this' thought...
Base is a tree management class. The nested class is a tree class and its constructor builds an entire tree in a neat, recursive, funky manner given the template data. However, there are many different sorts of trees that can be built for any given data type and thus, I want derived classes that use a common interface to a) generate specialised tree types governed by the derived class; and, b) specialise the access methods to the tree depending on what sort of tree it is. I had wanted to do this within object creation and so I had constructed the above heirarchy. However, unless I start bastardising the creation process, the better way would probably be to accept the lesser method of using an Init() function (which requires two lines of code to generate a new tree, as opposed to one). This isn't a huge overhead... it just makes the use of these trees a little more error prone, since you have to create the handler and then initialise the tree.
As for that being confusing code... why do you say that (ignoring the fact that I didn't bother to document it because its a trivially simple example).
Cheers,
Timkin
To answer the: 'why am I doing this' thought...
Base is a tree management class. The nested class is a tree class and its constructor builds an entire tree in a neat, recursive, funky manner given the template data. However, there are many different sorts of trees that can be built for any given data type and thus, I want derived classes that use a common interface to a) generate specialised tree types governed by the derived class; and, b) specialise the access methods to the tree depending on what sort of tree it is. I had wanted to do this within object creation and so I had constructed the above heirarchy. However, unless I start bastardising the creation process, the better way would probably be to accept the lesser method of using an Init() function (which requires two lines of code to generate a new tree, as opposed to one). This isn't a huge overhead... it just makes the use of these trees a little more error prone, since you have to create the handler and then initialise the tree.
As for that being confusing code... why do you say that (ignoring the fact that I didn't bother to document it because its a trivially simple example).
Cheers,
Timkin
Oh yeah, not sure if you realise this but a nested class isn't associated with an instance of the nesting class. The only relation is that the class is a member and can therefore see private and protected members of the nesting class.
It's generally not a good idea to call virtual functions from base constructors because the derived class hasn't been constructed yet.
Quote:Original post by joanusdmentia
Oh yeah, not sure if you realise this but a nested class isn't associated with an instance of the nesting class. The only relation is that the class is a member and can therefore see private and protected members of the nesting class.
(Edited... I misread this and the subsequent post by the AP made me realise my mistake)...
What I want is that the nested class be hidden by the base class. The base class should be able to access the private and protected members of the nested class. As I understand it, this is the usual use of nested classes.
Timkin
[Edited by - Timkin on September 26, 2004 10:55:40 PM]
Quote:Original post by joanusdmentia
Oh yeah, not sure if you realise this but a nested class isn't associated with an instance of the nesting class. The only relation is that the class is a member and can therefore see private and protected members of the nesting class.
If you mean that NestedBase can access/see private and protected members in Base, then that's wrong. As it stands right now, it's not in the C++ standard. It's beying proposed as an amendment. So, use it at you own risk, since some of the compiler will allow and some of them will not.
For reference see:
C/C++ User Journal, October 2004, "Frinedly Nesting" article by Herb Sutter and Jim Hyslop.
Quote:Original post by Timkin
What I want is that the nested class be hidden by the base class. The base class should be able to access the private and protected members of the nested class. As I understand it, this is the usual use of nested classes.
As far as I know a class cannot access the protected and private members of a nested class, I just double checked in gcc 3.2 and it didn't work with that. Not sure what the standard says though.
Quote:If you mean that NestedBase can access/see private and protected members in Base, then that's wrong. As it stands right now, it's not in the C++ standard. It's beying proposed as an amendment. So, use it at you own risk, since some of the compiler will allow and some of them will not.
Hmm, didn't realize that. I've used it a couple of times without any problems with both vc++ and gcc, so I'd say it's still relatively safe to use, but no, not guarentteed.
Quote:
As for that being confusing code... why do you say that (ignoring the fact that I didn't bother to document it because its a trivially simple example).
I guess it was just because I was tired and wondering what you were using it for. Also since it's in a webbrowser and all the classes are together.
oh, and thanks for the explanation as to the why.
This topic is closed to new replies.
Advertisement
Popular Topics
Advertisement