-
static function to call member function on all objects?
Hello all,
I'm working in Borland C++ Builder v6.0 (maintenance/rewriting some code). I have a class where I'd like to have a static function call a member function on all instantiated members of the class. (Motive: update all at once, where the update function only exists as a member of the base class.)
The way I thought to do this was to have a vector of pointers to the class inside the class itself. Upon construction, each object would add its "this" pointer to the vector. Then on calling the static function, iterate through all pointers in the vector, calling the update function.
It seems the linker doesn't like something about the vector, I get:
"[Linker Error] Unresolved external 'MyClass::vec' referenced from PATH\FILENAME.OBJ"
I was just trying a dummy class to prove it was doable. Am I doing something wrong? Or is this not possible? (If not, why not?)
Code is below. Thanks.
Code:
#include <vcl.h>
#include <vector>
#pragma hdrstop
using std::vector;
//---------------------------------------------------------------------------
class MyClass {
public:
MyClass();
private:
static vector<MyClass*> vec;
int m;
};
MyClass::MyClass() {
vec.push_back(this);
}
//---------------------------------------------------------------------------
#pragma argsused
int main(int argc, char* argv[])
{
MyClass mc;
return 0;
}
-
Re: static function to call member function on all objects?
You declared the vector, but never defined it. Define it in a source file. You probably need to have the destructor remove the object from the vector.
-
Re: static function to call member function on all objects?
Quote:
Originally Posted by
laserlight
You declared the vector, but never defined it. Define it in a source file.
I'm not sure what syntax I would use for this. (I made a couple attempts already.)
Also, for this simple dummy example, I would think I could just define it below the declaration. Correct?
Quote:
You probably need to have the destructor remove the object from the vector.
I plan to, after I get the first part working. I didn't think that would be required just to demonstrate the point. Please correct me if I'm wrong.
Thanks.
-
Re: static function to call member function on all objects?
Quote:
Originally Posted by cpengr
I'm not sure what syntax I would use for this. (I made a couple attempts already.)
For example:
Code:
vector<MyClass*> MyClass::vec;
-
Re: static function to call member function on all objects?
Quote:
Originally Posted by
laserlight
For example:
Code:
vector<MyClass*> MyClass::vec;
That worked, thanks!
(Somehow that syntax seems backwards to me, I didn't think of it..)
-
Re: static function to call member function on all objects?
Why don't you have a static class member instead and just change that? Have the objects themselves check it before they do anything to see if an update is needed.
-
Re: static function to call member function on all objects?
Quote:
Originally Posted by
cpengr
Hello all,
I'm working in Borland C++ Builder v6.0 (maintenance/rewriting some code). I have a class where I'd like to have a static function call a member function on all instantiated members of the class. (Motive: update all at once, where the update function only exists as a member of the base class.)
The way I thought to do this was to have a vector of pointers to the class inside the class itself. Upon construction, each object would add its "this" pointer to the vector. Then on calling the static function, iterate through all pointers in the vector, calling the update function.
May I recommend using a Set instead (while you are going for a container solution)?
Using a vector will give you big performance hit every time you destroy an object. You may think this doesn't happen too often, but keep in mind that when a vector re-allocates, for example, all of its content is re-built and re-constructed.
-
Re: static function to call member function on all objects?
Quote:
Originally Posted by
originalfamousjohnsmith
Why don't you have a static class member instead and just change that? Have the objects themselves check it before they do anything to see if an update is needed.
I couldn't figure a way to implement this. An "update individual" member function needs to be called once on every object when the static "update all" function is called. If I e.g. have a bool saying that "update all" has been called, set it true...how would I know when every individual object has been updated so I can set it false?
-
Re: static function to call member function on all objects?
Quote:
Originally Posted by
monarch_dodra
May I recommend using a Set instead (while you are going for a container solution)?
Using a vector will give you big performance hit every time you destroy an object. You may think this doesn't happen too often, but keep in mind that when a vector re-allocates, for example, all of its content is re-built and re-constructed.
Cool, thanks, I will probably use that.
-
Re: static function to call member function on all objects?
The set seems to work nicely. Easier to erase items, too.
Code:
#include <vcl.h>
#include <set>
#include <iostream>
#pragma hdrstop
using std::cout;
using std::set;
//---------------------------------------------------------------------------
class MyClass {
public:
MyClass();
~MyClass();
private:
static int count;
static set<MyClass*> setOfPtrs;
int num;
};
set<MyClass*> MyClass::setOfPtrs;
int MyClass::count = 0;
MyClass::MyClass() {
num = count;
cout << "creating " << num << '\n';
count++;
setOfPtrs.insert(this);
}
MyClass::~MyClass() {
cout << "destroying " << num << '\n';
count--;
if (setOfPtrs.find(this) != setOfPtrs.end()) {
cout << "\t(destructor found ptr.)\n";
}
setOfPtrs.erase(setOfPtrs.find(this));
}
//---------------------------------------------------------------------------
void doit() {
MyClass m1, m2, m3;
}
//---------------------------------------------------------------------------
#pragma argsused
int main(int argc, char* argv[])
{
doit();
return 0;
}
-
Re: static function to call member function on all objects?
Upon further inspection, this code, does not behave as I expected. The code is shown below, followed by its output.
Questions:
1.) In doit(), object #4 is destroyed right after it is created. I would expect that #2 should be destroyed, as #4 was assigned to #2's...reference? What is going on here?
2.) Also in doit(), notice that #4 and #5 are reportedly destroyed twice; and #1 and #2 are never shown as being destroyed. How/why?
3.) Regarding doitVecNoRef(), I guess these objects are going out of scope (from the for-loop)? Is there no way to populate a container of objects like this (conditionally or in a for-loop) and have the container handle the memory management? (I thought that's what they were for..?) Must I instead use a container of pointers to the objects with new/delete?
Code:
//---------------------------------------------------------------------------
#include <vcl.h>
#include <set>
#include <vector>
#include <iostream>
#pragma hdrstop
using std::cout;
using std::set;
using std::vector;
//---------------------------------------------------------------------------
class MyClass {
public:
MyClass();
~MyClass();
private:
static int count;
static set<MyClass*> setOfPtrs;
int num;
};
set<MyClass*> MyClass::setOfPtrs;
int MyClass::count = 0;
MyClass::MyClass() {
num = ++count;
setOfPtrs.insert(this);
cout << "creating " << num << "; "
<< setOfPtrs.size() << " objects exist.\n";
}
MyClass::~MyClass() {
if (setOfPtrs.find(this) == setOfPtrs.end()) {
cout << "\t(destructor " << num
<< " could not find ptr!!)\n";
} else {
cout << "destroying " << num << "; ";
setOfPtrs.erase(setOfPtrs.find(this));
cout << setOfPtrs.size() << " objects exist.\n";
}
}
//---------------------------------------------------------------------------
void doit() {
MyClass m1, m2, m3;
m2 = MyClass();
MyClass m4;
m1 = m4;
}
//---------------------------------------------------------------------------
void doitVecNoRef() {
vector<MyClass> myVec;
for (int i=0; i<3; i++) {
myVec.push_back(MyClass());
}
}
//---------------------------------------------------------------------------
#pragma argsused
int main(int argc, char* argv[])
{
doit();
cout << '\n';
doitVecNoRef();
cout << '\n';
return 0;
}
//---------------------------------------------------------------------------
Output is as follows:
creating 1; 1 objects exist.
creating 2; 2 objects exist.
creating 3; 3 objects exist.
creating 4; 4 objects exist.
destroying 4; 3 objects exist.
creating 5; 4 objects exist.
destroying 5; 3 objects exist.
destroying 3; 2 objects exist.
destroying 4; 1 objects exist.
destroying 5; 0 objects exist.
creating 6; 1 objects exist.
destroying 6; 0 objects exist.
creating 7; 1 objects exist.
(destructor 6 could not find ptr!!)
destroying 7; 0 objects exist.
creating 8; 1 objects exist.
(destructor 6 could not find ptr!!)
(destructor 7 could not find ptr!!)
destroying 8; 0 objects exist.
(destructor 6 could not find ptr!!)
(destructor 7 could not find ptr!!)
(destructor 8 could not find ptr!!)
-
Re: static function to call member function on all objects?
Quote:
Originally Posted by
cpengr
Upon further inspection, this code, does not behave as I expected.
That is because you didn't consider that the compiler optimized your code.
After you assigned to m2, you don't use it again, so the compiler is free to remove the object immediately. If you did something with m2 after you assigned it a MyClass(), then the compiler would not have destroyed the object. Not only that, the compiler is free to optimize away copy construction altogether. Change the compiler options, and you more than likely will see different output. So it really makes no sense trying to beat a dead horse -- change settings, you have a different outcome, change compilers (or even compiler versions), you may get another outcome.
The bottom line is this -- do not write code assuming you can predict when any object will be destroyed (unless you dynamically created the object yourself, or the objects are not temporary). The thing you are seeing with your output is the way your compiler creates and destroys objects that are not dynamically created, and as far as I can tell, the compiler is not breaking any rules.
Regards,
Paul McKenzie
-
Re: static function to call member function on all objects?
Quote:
Originally Posted by
Paul McKenzie
That is because you didn't consider that the compiler optimized your code.
Thanks for your reply. I think there is more going on here than that, though. My compiler settings seem to show no optimizations:
Project -> Options -> Compiler -> Code optimization = None
Also, I added a Print() function to use the objects, and the results are mostly the same. See below.
Quote:
The bottom line is this -- do not write code assuming you can predict when any object will be destroyed (unless you dynamically created the object yourself, or the objects are not temporary). The thing you are seeing with your output is the way your compiler creates and destroys objects that are not dynamically created, and as far as I can tell, the compiler is not breaking any rules.
Here, I would expect each object's this pointer to be added to the setOfPtrs at construction, and to be removed from setOfPtrs at destruction. However, it seems that one's destructor is removing another's this pointer...or these objects are being destroyed before their final usage...or they're intermingling somehow...?
What am I doing wrong?
Thanks.
Code:
//---------------------------------------------------------------------------
#include <vcl.h>
#include <set>
#include <vector>
#include <iostream>
#pragma hdrstop
using std::cout;
using std::set;
using std::vector;
//---------------------------------------------------------------------------
class MyClass {
public:
MyClass();
~MyClass();
void Print();
private:
static int count;
static set<MyClass*> setOfPtrs;
int num;
};
set<MyClass*> MyClass::setOfPtrs;
int MyClass::count = 0;
MyClass::MyClass() {
num = ++count;
setOfPtrs.insert(this);
cout << "creating " << num << "; "
<< setOfPtrs.size() << " objects exist.\n";
}
MyClass::~MyClass() {
if (setOfPtrs.find(this) == setOfPtrs.end()) {
cout << "\t(destructor " << num
<< " could not find ptr!!)\n";
} else {
cout << "destroying " << num << "; ";
setOfPtrs.erase(setOfPtrs.find(this));
cout << setOfPtrs.size() << " objects exist.\n";
}
}
void MyClass::Print() {
cout << " #" << num << " exists\n";
}
//---------------------------------------------------------------------------
void doit() {
cout << "doit:\n";
MyClass m1, m2, m3;
m1.Print();
m2.Print();
m3.Print();
m2 = MyClass();
m2.Print();
MyClass m4;
m4.Print();
m1 = m4;
m1.Print();
}
//---------------------------------------------------------------------------
void doitVecNoRef() {
cout << "doitVecNoRef:\n";
vector<MyClass> myVec;
for (int i=0; i<3; i++) {
myVec.push_back(MyClass());
}
for (vector<MyClass>::iterator it=myVec.begin(); it != myVec.end(); it++) {
it->Print();
}
}
//---------------------------------------------------------------------------
#pragma argsused
int main(int argc, char* argv[])
{
doit();
cout << "\n\n";
doitVecNoRef();
cout << "\n\n";
return 0;
}
//---------------------------------------------------------------------------
Output:
Code:
doit:
creating 1; 1 objects exist.
creating 2; 2 objects exist.
creating 3; 3 objects exist.
#1 exists
#2 exists
#3 exists
creating 4; 4 objects exist.
destroying 4; 3 objects exist.
#4 exists
creating 5; 4 objects exist.
#5 exists
#5 exists
destroying 5; 3 objects exist.
destroying 3; 2 objects exist.
destroying 4; 1 objects exist.
destroying 5; 0 objects exist.
doitVecNoRef:
creating 6; 1 objects exist.
destroying 6; 0 objects exist.
creating 7; 1 objects exist.
(destructor 6 could not find ptr!!)
destroying 7; 0 objects exist.
creating 8; 1 objects exist.
(destructor 6 could not find ptr!!)
(destructor 7 could not find ptr!!)
destroying 8; 0 objects exist.
#6 exists
#7 exists
#8 exists
(destructor 6 could not find ptr!!)
(destructor 7 could not find ptr!!)
(destructor 8 could not find ptr!!)
-
Re: static function to call member function on all objects?
Remember objects in stl containers are copied in and copied out. You store the this of a temporary yet this gets copied into the vector. MyClass relies on a default copy constructor, so your set becomes out-of-sync with the real this pointers.
Provide a copy constructor that updates the set correctly.
-
Re: static function to call member function on all objects?
Quote:
Originally Posted by
cpengr
Thanks for your reply. I think there is more going on here than that, though. My compiler settings seem to show no optimizations:
Well, you're making my point.
What if when optimizations are turned on (which you want turned on for release versions of your code), the output is different? What do you do then?
Hopefully you are observing this behaviour only for educational purposes. If you are truly planning on writing a program based on when objects destroy themselves, then you're going about this the wrong way.
Regards,
Paul McKenzie
-
Re: static function to call member function on all objects?
Quote:
Originally Posted by
Russco
Remember objects in stl containers are copied in and copied out.
Ah, I had forgotten.
Quote:
You store the this of a temporary yet this gets copied into the vector. MyClass relies on a default copy constructor, so your set becomes out-of-sync with the real this pointers.
Provide a copy constructor that updates the set correctly.
Are you saying that the objects are being copied, or that the pointers are being copied?
1.) If the objects are being copied, why? The container only holds pointers to the objects.
2.) Or are the pointers being copied, and then the objects are being moved around in memory, such that the copies of the pointers no longer point to the objects?
Quote:
Originally Posted by
Paul McKenzie
Well, you're making my point.
What if when optimizations are turned on (which you want turned on for release versions of your code), the output is different? What do you do then?
Hopefully you are observing this behaviour only for educational purposes. If you are truly planning on writing a program based on when objects destroy themselves, then you're going about this the wrong way.
Regards,
Paul McKenzie
Thanks for the warning...
It was never my intent to rely on some "compiler quirk" to get my program working. I'm just not clear on what's happening here, or what assumptions I have that are causing me to expect something else to occur...
My goal is to have a class which contains a static function which, when called, calls a member function on all instances of the class. My purpose for the code shown above was just to be a proof of concept, that I could track all the existing instances of the class--I probably would have added the static function next. However, it seems some instances are being destroyed before I expect, or there are copies taking place that I'm unaware of, or the pointers in the set are being invalidated, or...?
So, if I am going about this the wrong way, can you suggest a right way?
Thanks.
-
Re: static function to call member function on all objects?
Quote:
Originally Posted by
cpengr
My purpose for the code shown above was just to be a proof of concept, that I could track all the existing instances of the class--
Copying an object should be considered a "base" or "atomic" operation in C++. You do not have total control on when copying takes place or not, unless you make the copy constructor (which you didn't consider) private (then no copying would be allowed at compile-time).
Quote:
However, it seems some instances are being destroyed before I expect, or there are copies taking place that I'm unaware of,
Again, you never write a C++ program that depends on when or where copies are done.
The compiler can make copies automatically if you pass by value, return by value, use conversion operators, etc. In this case, none of those copies were generated by you explicitly. Similarly, the compiler is free to remove copying and instances of objects due to optimizations (Return Value Optimization is one such optmization technique).
Trying to track instances exactly just doesn't work, unless you are writing some sort of program that tests compilers and how they behave, or some similar utility. The main reason why it isn't a good idea to write a program in the way you have done is that your program will experience different behaviour depending on compiler optimizations, options, etc. You upgrade the compiler to a later version, and yet again, the same program you wrote may have different behaviour.
Quote:
So, if I am going about this the wrong way, can you suggest a right way?
1) Store pointers in the vector.
2) Turn off the copying completely by making the copy constructor and assignment operator private and unimplemented.
3) Add a static function to the class to explicitly create objects so that the compiler has no chance of doing so itself. Then the user just can't create objects on the fly by just declaring them -- you have total control over how the objects are created, i.e. the factory pattern.
Regards,
Paul McKenzie
-
Re: static function to call member function on all objects?
Thanks for the detailed answer (including the part I'm not quoting here).
Quote:
Originally Posted by
Paul McKenzie
1) Store pointers in the vector.
2) Turn off the copying completely by making the copy constructor and assignment operator private and unimplemented.
3) Add a static function to the class to explicitly create objects so that the compiler has no chance of doing so itself. Then the user just can't create objects on the fly by just declaring them -- you have total control over how the objects are created, i.e. the factory pattern.
Factory pattern, hrm. I did a little reading, and...this is starting to seem like more trouble than it's worth. I was trying to make things easier for the end-user of this class (just me, so far). I think since I will have a known, finite amount of instances, it will be easier to just make an array of "MyClass"es, and make a (static or non-member) function that calls the member function on all of them. I think this will be easier to maintain, whether by me or someone else. I'm interested to know if you think otherwise.
I'm an EE, working on my master's in CpE...some of the more "esoteric" aspects of s/w design have eluded me thus far...
-
Re: static function to call member function on all objects?
What I was explaining was in the code you stuff default constructed objects into a vector.
First the default object gets created. At creation the this pointer is stored in the set. This 'this pointer' points to a temporary object.
Second this default constructed object is passed as a parameter to vector::push_back which COPIES that object into the vector. Where does this copy come from? It comes from the copy constructor that because you neither provided one nor disallowed it, the compiler nicely generated for you. However that implicit copy constructor does not cause the set to be updated to reflect the new object in existence. Its why you get all those could not find pointer in set messages.
Whilst Paul is telling you never to write code that depends on destruction order that you cannot manage, I'm pointing out that you haven't even correctly kept a tab on 'live objects'.
-
Re: static function to call member function on all objects?
all you need to do is implement the
MyClass(const MyClass& p); // copy constructor
MyClass& operator =( const MyClass& cpy ); //(optional) assignment
in short make these add the this pointer to the container.
or you can do what paul said.
-
Re: static function to call member function on all objects?
Quote:
Originally Posted by
Russco
What I was explaining was in the code you stuff default constructed objects into a vector.
First the default object gets created. At creation the this pointer is stored in the set. This 'this pointer' points to a temporary object.
Second this default constructed object is passed as a parameter to vector::push_back which COPIES that object into the vector. Where does this copy come from? It comes from the copy constructor that because you neither provided one nor disallowed it, the compiler nicely generated for you. However that implicit copy constructor does not cause the set to be updated to reflect the new object in existence. Its why you get all those could not find pointer in set messages.
Whilst Paul is telling you never to write code that depends on destruction order that you cannot manage, I'm pointing out that you haven't even correctly kept a tab on 'live objects'.
Ah-hah! That helps clarify what's happening, thank you.
Quote:
Originally Posted by
Joeman
all you need to do is implement the
MyClass(const MyClass& p); // copy constructor
MyClass& operator =( const MyClass& cpy ); //(optional) assignment
in short make these add the this pointer to the container.
or you can do what paul said.
Okay, so by adding a copy constructor, and disallowing assignment (and subsequently remming assignments in doit())...
Code:
//---------------------------------------------------------------------------
#include <vcl.h>
#include <set>
#include <vector>
#include <iostream>
#pragma hdrstop
using std::cout;
using std::set;
using std::vector;
//---------------------------------------------------------------------------
class MyClass {
public:
MyClass();
~MyClass();
MyClass(const MyClass& ref); // copy constructor
void Print();
private:
static int count;
static set<MyClass*> setOfPtrs;
int num;
MyClass& operator=(const MyClass& cpy); // disallow assignment
};
set<MyClass*> MyClass::setOfPtrs;
int MyClass::count = 0;
MyClass::MyClass() {
num = ++count;
setOfPtrs.insert(this);
cout << "creating " << num << "; "
<< setOfPtrs.size() << " objects exist.\n";
}
MyClass::~MyClass() {
if (setOfPtrs.find(this) == setOfPtrs.end()) {
cout << "\t(destructor " << num
<< " could not find ptr!!)\n";
} else {
cout << "destroying " << num << "; ";
setOfPtrs.erase(setOfPtrs.find(this));
cout << setOfPtrs.size() << " objects exist.\n";
}
}
MyClass::MyClass(const MyClass& ref) { // copy constructor
num = ++count;
setOfPtrs.insert(this);
cout << "creating " << num << ", copy of " << ref.num << "; "
<< setOfPtrs.size() << " objects exist.\n";
}
void MyClass::Print() {
cout << " #" << num << " exists\n";
}
//---------------------------------------------------------------------------
void doit() {
cout << "doit:\n";
MyClass m1, m2, m3;
m1.Print();
m2.Print();
m3.Print();
//m2 = MyClass();
//m2.Print();
MyClass m4;
m4.Print();
//m1 = m4;
//m1.Print();
}
//---------------------------------------------------------------------------
void doitVecNoRef() {
cout << "doitVecNoRef:\n";
vector<MyClass> myVec;
for (int i=0; i<3; i++) {
myVec.push_back(MyClass());
}
for (vector<MyClass>::iterator it=myVec.begin(); it != myVec.end(); it++) {
it->Print();
}
}
//---------------------------------------------------------------------------
void doitVecOfPtrs() {
cout << "doitVecOfPtrs:\n";
vector<MyClass*> myVec;
for (int i=0; i<3; i++) {
myVec.push_back(&MyClass());
}
for (vector<MyClass*>::iterator it=myVec.begin(); it != myVec.end(); it++) {
(*it)->Print();
}
}
//---------------------------------------------------------------------------
#pragma argsused
int main(int argc, char* argv[])
{
doit();
cout << "\n\n";
doitVecNoRef();
cout << "\n\n";
doitVecOfPtrs();
cout << "\n\n";
return 0;
}
//---------------------------------------------------------------------------
I get
Code:
doit:
creating 1; 1 objects exist.
creating 2; 2 objects exist.
creating 3; 3 objects exist.
#1 exists
#2 exists
#3 exists
creating 4; 4 objects exist.
#4 exists
destroying 4; 3 objects exist.
destroying 3; 2 objects exist.
destroying 2; 1 objects exist.
destroying 1; 0 objects exist.
doitVecNoRef:
creating 5; 1 objects exist.
creating 6, copy of 5; 2 objects exist.
destroying 5; 1 objects exist.
creating 7; 2 objects exist.
creating 8, copy of 6; 3 objects exist.
creating 9, copy of 7; 4 objects exist.
destroying 6; 3 objects exist.
destroying 7; 2 objects exist.
creating 10; 3 objects exist.
creating 11, copy of 8; 4 objects exist.
creating 12, copy of 9; 5 objects exist.
creating 13, copy of 10; 6 objects exist.
destroying 8; 5 objects exist.
destroying 9; 4 objects exist.
destroying 10; 3 objects exist.
#11 exists
#12 exists
#13 exists
destroying 11; 2 objects exist.
destroying 12; 1 objects exist.
destroying 13; 0 objects exist.
doitVecOfPtrs:
creating 14; 1 objects exist.
destroying 14; 0 objects exist.
creating 15; 1 objects exist.
destroying 15; 0 objects exist.
creating 16; 1 objects exist.
destroying 16; 0 objects exist.
#16 exists
#16 exists
#16 exists
In this case, that's 3x as many created vs. how many are needed, for use in the vector. I think they are created when the vector capacity is enlarged, and then by the MyClass() inside the push_back, then copied by the insertion (push_back). Using vector::reserve(), I was able to cut it down to just the copy for insertion.
Some questions remain:
1. Is it possible to populate a container of MyClass objects without any copies being performed, and without having individual variable names for each? (i.e. I don't want to have
MyClass m1;
MyClass m2;
//...
myVec.push_back(m1);
myVec.push_back(m2);
//... )
2. ...using a non-default constructor?
Thanks again, all.
-
Re: static function to call member function on all objects?
Quote:
Originally Posted by cpengr
1. Is it possible to populate a container of MyClass objects without any copies being performed, and without having individual variable names for each? (i.e. I don't want to have
you mean like
vector<MyClass*> myVec;
myVec.push_back( new MyClass() );
? perhaps you want to use the list container as well.
make sure you delete them too
-
Re: static function to call member function on all objects?
Quote:
Originally Posted by
Joeman
you mean like
vector<MyClass*> myVec;
myVec.push_back( new MyClass() );
Quote:
make sure you delete them too
That crossed my mind. Ironically, part of what drew me to STL containers was not having to manage memory...oh well, guess I can't have my cake & eat it, too...but I do like to know what kinds of cake are available. ;)
Quote:
? perhaps you want to use the list container as well.
Probably not in this situation, but thanks for the reminder.
-
Re: static function to call member function on all objects?
Quote:
Originally Posted by cpengr
That crossed my mind. Ironically, part of what drew me to STL containers was not having to manage memory...
Well, you do not have the manage the memory of the dynamic array of pointers even though you have to manage the memory for the object associated with each pointer.
Quote:
Originally Posted by cpengr
oh well, guess I can't have my cake & eat it, too...but I do like to know what kinds of cake are available.
If a TR1 implementation is available, you can use a std::vector<std::tr1::shared_ptr<MyClass> > instead. If Boost is available you could use a boost::ptr_vector<MyClass>. You could always wrap the vector with another class whose sole duty is to perform memory management for the object associated with each pointer in the vector.
-
Re: static function to call member function on all objects?
Quote:
Originally Posted by
laserlight
Quote:
Originally Posted by
cpengr
Ironically, part of what drew me to STL containers was not having to manage memory...
Well, you do not have the manage the memory of the dynamic array of pointers even though you have to manage the memory for the object associated with each pointer.
Good point. I think maybe I will have my "main class" create the collection in its constructor, and destroy it in its destructor...such that the objects in the collection will persist through the duration of the program and be reused, vs. being created and destroyed every time the user clicks "start".
Quote:
If a TR1 implementation is available, you can use a std::vector<std::tr1::shared_ptr<MyClass> > instead. If
Boost is available you could use a boost::ptr_vector<MyClass>. You could always wrap the vector with another class whose sole duty is to perform memory management for the object associated with each pointer in the vector.
I'm using Borland C++ Builder v6. I don't think it's worth the trouble in this case. Thanks for the pointer, though. (No pun intended.)
-
Re: static function to call member function on all objects?
No extra copies...
Code:
void doitVecNew() {
cout << "doitVecNew:\n";
cout << " create myVec<MyClass*>...\n";
vector<MyClass*> myVec;
cout << " populate myVec (push_back(new MyClass())):\n";
for (int i=0; i<3; i++) {
myVec.push_back(new MyClass());
}
cout << " delete members of myVec:\n";
for (int i=0; i<3; i++) {
delete myVec[i];
}
cout << " finished deletions, exiting doitVecNew...\n";
}
//---------------------------------------------------------------------------
#pragma argsused
int main(int argc, char* argv[])
{
doitVecNew();
return 0;
}
Output:
Code:
doitVecNew:
create myVec<MyClass*>...
populate myVec (push_back(new MyClass())):
creating 25; 1 objects exist.
creating 26; 2 objects exist.
creating 27; 3 objects exist.
delete members of myVec:
destroying 25; 2 objects exist.
destroying 26; 1 objects exist.
destroying 27; 0 objects exist.
finished deletions, exiting doitVecNew...
-
Re: static function to call member function on all objects?
This seems appropriate:
Quote:
[In] C, you shoot yourself in the foot.
[In] C++, you accidentally create a dozen instances of yourself and shoot them all in the foot. Providing emergency medical assistance is impossible since you can't tell which are bitwise copies and which are just pointing at others and saying, "That's me, over there."
Excerpted from http://www.softpanorama.org/Lang/Cpp_rama/humor.shtml.