 |
C++Talk.NET C++ language newsgroups
|
| View previous topic :: View next topic |
| Author |
Message |
Guest
|
Posted: Mon Sep 18, 2006 9:10 am Post subject: parent's child list |
|
|
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
|
Posted: Mon Sep 18, 2006 9:10 am Post subject: Re: parent's child list |
|
|
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
|
Posted: Thu Sep 21, 2006 9:10 am Post subject: Re: parent's child list |
|
|
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
|
Posted: Thu Sep 21, 2006 9:10 am Post subject: Re: parent's child list |
|
|
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
|
Posted: Thu Sep 21, 2006 9:10 am Post subject: Re: parent's child list |
|
|
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 |
|
 |
|
|
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
|
|