Sign in to follow this  
ttdeath

How to access derived class members from base class?

Recommended Posts

I need a function from the derived class called by the constructor of the base class. I realise that this SHOULD not be possible, but I am asking just in case I am missing something. (pure virtual won't work as I have already found out.. nor was it supposed to, if my OO knowledge is right) The reason for calling the derived class member is that the base class generates several allocated spaces that need to be filled with content, depending on what the derived class is, and that I want to have the absolute minimal implementation in the derived classes. Something like the following pseudo-pode.. code: class a { allocator(void *adr); } class b : public class a { allocator_user(); } a::allocator(void *adr) { for each loaded info { new_pointer = create_new_memory_zone(); b::allocator_user(new_pointer); } } At this time I am thinking (with heavy heart) of moving the loop into the derived class and use iterating allocation in the base class (iterates the info from which it knows how to allocate how many pointers). If you see a solution where I could leave the power in the base class, please let me know. Tudor Tihan

Share this post


Link to post
Share on other sites
Quote:
Original post by ttdeath
I need a function from the derived class called by the constructor of the base class.

It's not possible, since the derived class doesn't exist while in the base class' constructor. You can pass type information to your base class from your derived class' constructor, though.

Share this post


Link to post
Share on other sites
Curiously recurring template pattern?
template < typename AllocationUser >
class A
{

public:

A()
{
for (loop_condition)
{
AllocationUser::doSomething(*this, other_parameters)
}
}

};

class B
:
public A< B >
{

public:

B()
{
// stuff
}

static void doSomething(A< B > & object, Thing parameters)
{
// do what you wanted to do
}

}

EDIT: thinking about it a bit more, and depending on your actual design and the specifics of what you want to do you could also pass a function object to the base class, possibly binding parameters from the derived class before passing it.

Enigma

Share this post


Link to post
Share on other sites
Quote:
Original post by Enigma
Curiously recurring template pattern?
*** Source Snippet Removed ***
EDIT: thinking about it a bit more, and depending on your actual design and the specifics of what you want to do you could also pass a function object to the base class, possibly binding parameters from the derived class before passing it.

Enigma


Thanks Enigma, this is awesome. I tried it and it works (spent a few minutes in the dark because I am a newby as far as templates are concerned, but after a while I saw the ";" missing from the second class and everything compiled ok). In any case, can you please explain in a little more detail the other solution you gave me? Did you mean for me to pass a function pointer to the base class?

Share this post


Link to post
Share on other sites
Quote:
Original post by ttdeath
...spent a few minutes in the dark because I am a newby as far as templates are concerned, but after a while I saw the ";" missing from the second class and everything compiled ok.

Oops, sorry about that!
Quote:
In any case, can you please explain in a little more detail the other solution you gave me? Did you mean for me to pass a function pointer to the base class?

Kind of, although a function object is more powerful than a plain function pointer. Here's a silly example of what I meant:
#include <iostream>
#include <iterator>
#include <boost/bind.hpp>
#include <boost/function.hpp>

class GeometricSequence
{

public:

GeometricSequence(boost::function1< float, unsigned int > function)
{
for (int index = 0; index < 16; ++index)
{
data_[index] = function(index);
}
}

void print() const
{
std::copy(data_, data_ + 16, std::ostream_iterator< float >(std::cout, "\n"));
}

private:

float data_[16];

};

class SquaresPlusX
:
public GeometricSequence
{

public:

SquaresPlusX(float x)
:
GeometricSequence(boost::bind(&SquaresPlusX::generate, _1, x))
{
}

private:

static float generate(unsigned int index, float offset)
{
return float(index * index) + offset;
}

};

class CubesFromXTimesY
:
public GeometricSequence
{

public:

CubesFromXTimesY(unsigned x, float y)
:
GeometricSequence(boost::bind(&CubesFromXTimesY::generate, _1, x, y))
{
}

private:

static float generate(unsigned int index, unsigned int offset, float multiplier)
{
index += offset;
return float(index * index * index) * multiplier;
}

};

int main()
{
SquaresPlusX squaresPlus10(10);
SquaresPlusX squaresPlus1337(1337);
CubesFromXTimesY cubesFrom0Times1(0, 1);
CubesFromXTimesY cubesFrom4Times0point5(4, 0.5f);
std::cout << "(x * x) + 10:\n";
squaresPlus10.print();
std::cout << "\n(x * x) + 1337:\n";
squaresPlus1337.print();
std::cout << "\nx * x * x:\n";
cubesFrom0Times1.print();
std::cout << "\n((x + 4) * (x + 4) * (x + 4)) / 2:\n";
cubesFrom4Times0point5.print();
}

Enigma

Share this post


Link to post
Share on other sites
Quote:
Original post by Enigma
Kind of, although a function object is more powerful than a plain function pointer. Here's a silly example of what I meant:
*** Source Snippet Removed ***
Enigma


Ok, I appreciate your effort very much and I think the first way is the thing I'm after. That and the fact that to my non-templated brain something like "boost::function1< float, unsigned int > function" reads "integer is bigger than function"... :)

And I am pretty convinced now that what I want to do is not possible using only non-templated C/C++.

So, I'll rate you and thank you again and shamelessly use your first solution.

Tudor Tihan

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this