By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
424,967 Members | 1,690 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 424,967 IT Pros & Developers. It's quick & easy.

parent's child list

P: n/a
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 (cm****@hotmail.com)

Sep 18 '06 #1
Share this Question
Share on Google+
5 Replies


P: n/a
cm****@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.

#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++){
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
Sep 18 '06 #2

P: n/a
Kai-Uwe Bux wrote:
cm****@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.

#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++){

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 ) {}

};
[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
Sep 21 '06 #3

P: n/a

Kai-Uwe Bux 寫道:
Kai-Uwe Bux wrote:
cm****@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.

#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++){
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 ) {}

};
[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
Hi i found a easy solution
in mother's constructor, just add the *this* pointer to the list

Sep 21 '06 #4

P: n/a
pa**************************@hotmail.com wrote:
>
Kai-Uwe Bux ???
>Kai-Uwe Bux wrote:
cm****@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
Sep 21 '06 #5

P: n/a

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

Sep 21 '06 #6

This discussion thread is closed

Replies have been disabled for this discussion.