Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

parent's child list

37 views
Skip to first unread message

cmk...@hotmail.com

unread,
Sep 18, 2006, 3:12:05 AM9/18/06
to
Hi All
Is there any alternative way to let parent class hold a vector of
its child class's objects?
I meant when i create an object from the child class, in the parent
class, i am able to reference that object.

#include <string>
#include <vector>
#include <iostream>

using namespace std;

class mother{
private:
protected:
vector <void *>list;
mother(){
}
public:
static mother * getInstance(){
static mother m;
return &m;
}

vector <void *> * getList(){
return &list;
}

};

class child : mother{
public:
child(){
cout<<"child()"<<endl;

mother::getInstance()->getList()->push_back((void *)this);

cout<<"list->size()="<<(int)mother::getInstance()->getList()->size()<<endl;
}

};

void dumpVector(vector <void *> *v){
for (int x=0;x<v->size();x++){
vector <void *>vv=*v;
int yy=(int)vv[x];
cout<<(*v)[x]<<endl;
}

}

int main(){
dumpVector(mother::getInstance()->getList());
child *c=new child();
dumpVector(mother::getInstance()->getList());
return 0;

}

thanks
from Peter (cmk...@hotmail.com)

Kai-Uwe Bux

unread,
Sep 18, 2006, 3:39:36 AM9/18/06
to
cmk...@hotmail.com wrote:

What is the purpose of the following two lines?

> vector <void *>vv=*v;
> int yy=(int)vv[x];
> cout<<(*v)[x]<<endl;
> }
>
> }
>
> int main(){
> dumpVector(mother::getInstance()->getList());
> child *c=new child();
> dumpVector(mother::getInstance()->getList());
> return 0;
>
> }

What is the problem that you are trying to solve?

Anyway, here is an idea without void* and without casting:

#include <vector>
#include <string>
#include <iostream>


class mother {

typedef mother* pointer;
typedef std::vector< pointer > instance_list;

static
instance_list &
get_instances ( void ) {
static instance_list instances;
return ( instances );
}

public:

mother ( void ) {
get_instances().push_back( this );
}

virtual
std::string get_name ( void ) const {
return ( "mother" );
}

static
void dump ( std::ostream& o_str ) {
for ( instance_list::const_iterator iter = get_instances().begin();
iter != get_instances().end(); ++iter ) {
o_str << (*iter)->get_name() << '\n';
}
}

virtual
~mother ( void ) {}

};


class child_a : public mother {
public:

child_a ( void ) : mother() {}

std::string get_name ( void ) const {
return ( "child_a" );
}

};

class child_b : public mother {
public:

child_b ( void ) : mother() {}

std::string get_name ( void ) const {
return ( "child_b" );
}

};

int main ( void ) {
mother a;
child_a b;
mother c;
child_a d;
child_b e;
mother::dump( std::cout );
}

Best

Kai-Uwe Bux

Kai-Uwe Bux

unread,
Sep 21, 2006, 1:42:59 AM9/21/06
to
Kai-Uwe Bux wrote:

[test code snipped]

Ok, I reconsidered. The above has some very visible shortcomings. In
particular, it only adds to the list but it never removes pointers from the
list when the pointees are destructed -- very bad. Also, I forgot about
copy constructors, ...

Here is another approach packaging the solution into a policy template from
which you derive:

#include <set>

template < typename T >
struct tracked {

typedef T * pointer;
typedef T & reference;

private:

typedef tracked * base_pointer;
typedef std::set< base_pointer > set_type;

public:

typedef typename set_type::size_type size_type;

struct obj_iterator : public set_type::const_iterator {

obj_iterator ( typename set_type::const_iterator it )
: set_type::const_iterator( it )
{}

reference operator* ( void ) const {
return ( * up_cast( set_type::const_iterator::operator*() ) );
}

pointer operator-> ( void ) const {
return ( up_cast( set_type::const_iterator::operator*() ) );
}

};

static
bool has_objects ( void ) {
return( ! the_set().empty() );
}

static
bool is_valid ( pointer * ptr ) {
return ( the_set().find( ptr ) != the_set().end() );
}

static
size_type num_objects ( void ) {
return ( the_set().size() );
}

static
obj_iterator obj_begin ( void ) {
return ( the_set().begin() );
}

static
obj_iterator obj_end ( void ) {
return ( the_set().end() );
}

protected:

tracked ( void ) {
the_set().insert( this );
}

tracked ( tracked const & ) {
the_set().insert( this );
}

~tracked ( void ) {
the_set().erase( this );
}

static
void create_set ( void ) {
the_set();
}

private:

static
pointer up_cast ( base_pointer bp ) {
return ( static_cast< pointer >( bp ) );
}

static
set_type & the_set ( void ) {
static set_type dummy;
return ( dummy );
}

}; // tracked


#include <iostream>

struct mother : public tracked< mother > {



virtual
std::string get_name ( void ) const {
return ( "mother" );
}

virtual
~mother ( void ) {
std::cout << "destroying " << get_name() << ".\n";
}

};

class child_a : public mother {
public:

child_a ( void ) : mother() {}

std::string get_name ( void ) const {
return ( "child_a" );
}

virtual
~child_a ( void ) {
std::cout << "destroying " << get_name() << ", ";


}

};

class child_b : public mother {
public:

child_b ( void ) : mother() {}

std::string get_name ( void ) const {
return ( "child_b" );
}

virtual
~child_b ( void ) {
std::cout << "destroying " << get_name() << ", ";
}

};

int main ( void ) {

new mother;
new child_a;
new mother;
new child_b;
new child_a;
for ( mother::obj_iterator iter = mother::obj_begin();
iter != mother::obj_end(); ++iter ) {
std::cout << iter->get_name() << '\n';
}
while ( mother::has_objects() ) {
delete ( mother::obj_begin().operator->() );
}
}


Best

Kai-Uwe Bux

paper_underwea...@hotmail.com

unread,
Sep 21, 2006, 3:49:30 AM9/21/06
to

Kai-Uwe Bux 寫道:

Hi i found a easy solution
in mother's constructor, just add the *this* pointer to the list

Kai-Uwe Bux

unread,
Sep 21, 2006, 4:41:07 AM9/21/06
to
paper_underwea...@hotmail.com wrote:

>
> Kai-Uwe Bux ???


>
>> Kai-Uwe Bux wrote:
>>
>> > cmk...@hotmail.com wrote:
>> >
>> >> Hi All
>> >> Is there any alternative way to let parent class hold a vector of
>> >> its child class's objects?
>> >> I meant when i create an object from the child class, in the parent
>> >> class, i am able to reference that object.
>

[tons of code snipped]


>
> Hi i found a easy solution
> in mother's constructor, just add the *this* pointer to the list

Well, that is more or less what I had in my first reply along with some test
code to demonstrate that it works, and it still is at the core of the
convoluted thing I submitted finally. But in fact, that alone does not
quite cut it: One problem is that you also need the destructor to remove
the pointer from the list, which makes std::set a better data structure for
this problem. Another problem is that you really do not want to expose the
list anyway since you should guarantee that it is *only* changed through
constructors/destructors of mother. These considerations led to the
somewhat longer approach. Wrapping the whole mess up into the tracked<>
template is just some syntactic sugar to turn the solution into something
generic I could add to my library. (It also makes maintenance of mother
easier: if you add a constructor, there is no danger to forget the update
of the list.)


Best

Kai-Uwe Bux

Kirit Sælensminde

unread,
Sep 21, 2006, 6:55:47 AM9/21/06
to

Kai-Uwe Bux wrote:
> Well, that is more or less what I had in my first reply along with some test
> code to demonstrate that it works, and it still is at the core of the
> convoluted thing I submitted finally. But in fact, that alone does not
> quite cut it: One problem is that you also need the destructor to remove
> the pointer from the list, which makes std::set a better data structure for
> this problem. Another problem is that you really do not want to expose the
> list anyway since you should guarantee that it is *only* changed through
> constructors/destructors of mother. These considerations led to the
> somewhat longer approach. Wrapping the whole mess up into the tracked<>
> template is just some syntactic sugar to turn the solution into something
> generic I could add to my library. (It also makes maintenance of mother
> easier: if you add a constructor, there is no danger to forget the update
> of the list.)

And then there's the multi-threading. There are a number of different
ways it should behave depending on what the instance list/set is used
for.

We have loads of slightly different implementations of this sort of
idea throughout our framework. I think it should be possible to hide it
all in library code by using an extra 'policy' template that implements
that part of it, but I've not spent any time thinking through how that
should work yet.


K

0 new messages