C++Talk.NET Forum Index C++Talk.NET
C++ language newsgroups
 
Archives   FAQFAQ   SearchSearch   MemberlistMemberlist   UsergroupsUsergroups   RegisterRegister 
 ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

parent's child list

 
Post new topic   Reply to topic    C++Talk.NET Forum Index -> C++ language (comp.lang.c++)
View previous topic :: View next topic  
Author Message
Guest






PostPosted: Mon Sep 18, 2006 9:10 am    Post subject: parent's child list Reply with quote



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 (cmk128 (AT) hotmail (DOT) com)
Back to top
Kai-Uwe Bux
Guest





PostPosted: Mon Sep 18, 2006 9:10 am    Post subject: Re: parent's child list Reply with quote



cmk128 (AT) hotmail (DOT) com wrote:

Quote:
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?

Quote:
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
Back to top
Kai-Uwe Bux
Guest





PostPosted: Thu Sep 21, 2006 9:10 am    Post subject: Re: parent's child list Reply with quote



Kai-Uwe Bux wrote:

Quote:
cmk128 (AT) hotmail (DOT) 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
Back to top
Guest






PostPosted: Thu Sep 21, 2006 9:10 am    Post subject: Re: parent's child list Reply with quote

Kai-Uwe Bux 寫道:

Quote:
Kai-Uwe Bux wrote:

cmk128 (AT) hotmail (DOT) 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
Back to top
Kai-Uwe Bux
Guest





PostPosted: Thu Sep 21, 2006 9:10 am    Post subject: Re: parent's child list Reply with quote

paper_underwear_poon_hoi_kan (AT) hotmail (DOT) com wrote:

Quote:

Kai-Uwe Bux ???

Kai-Uwe Bux wrote:

cmk128 (AT) hotmail (DOT) 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
Back to top
Display posts from previous:   
Post new topic   Reply to topic    C++Talk.NET Forum Index -> C++ language (comp.lang.c++) All times are GMT
Page 1 of 1

 
Jump to:  
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum


Powered by phpBB © 2001, 2006 phpBB Group
SEO toolkit © 2004-2006 webmedic.