From: dailos on 14 Jul 2010 21:03 Hi all, I am struggling with a design problem. It showed up because of some architectures constraints. I have a group of classes which derive from an abstract one. I have a vector with pointers to the generic abstract class (neither vector of references nor vector of classes are allowed since it's abstract). A member function that loads objects into the vector, lets say from file, has to do it creating object with new operator since it couldn't be done by references to objects created locally. A public functions lets the user to add single objects too but it could use new or reference as an argument. The problem is when I need to call the destructor, and erase all of the objects created within the vector. I thought of using delete operator for each element in the vector, but what if some other elements has been added from a reference. delete &something ## failure. I guess there is no way to distinguish between object address created with new and created with a reference. How a to write a proper destructor then?? Here it is a very easy program that shows the situation. Thanks!! #include <iostream> #include <vector> using namespace std; class Fruit { public: virtual string name() = 0; }; class Orange : public Fruit { public: virtual string name(){return string("Orange");}; }; class Watermelon : public Fruit { public: virtual string name(){return string("Watermelon");}; }; class Apple : public Fruit { public: virtual string name(){return string("Apple");}; }; class Basket { public: void loadFruits(); void addFruit(Fruit* pFruit); void showFruits(); private: vector<Fruit*> fruitList; }; void Basket::loadFruits() {//adds three fruits addFruit(new Watermelon()); addFruit(new Orange()); addFruit(new Apple()); } void Basket::addFruit(Fruit* pFruit) { fruitList.push_back(pFruit); } void Basket::showFruits() { for(unsigned int i=0;i<fruitList.size();++i) { cout << fruitList[i]->name() << endl; } } int main() { Basket myBasket; myBasket.loadFruits(); Orange theOrange; myBasket.addFruit(&theOrange); myBasket.showFruits(); return 0; } -- [ See http://www.gotw.ca/resources/clcm.htm for info about ] [ comp.lang.c++.moderated. First time posters: Do this! ]
From: Helge Kruse on 15 Jul 2010 10:39 "dailos" <dailos.guerra.r(a)gmail.com> wrote in message news:9887de25-e04b-411b-9347-df6419a7caea(a)d37g2000yqm.googlegroups.com... > Hi all, > I am struggling with a design problem. It showed up because of some > architectures constraints. > I have a group of classes which derive from an abstract one. > I have a vector with pointers to the generic abstract class (neither > vector of references nor vector of classes are allowed since it's > abstract). > A member function that loads objects into the vector, lets say from > file, has to do it creating object with new operator since it couldn't > be done by references to objects created locally. > A public functions lets the user to add single objects too but it > could use new or reference as an argument. > The problem is when I need to call the destructor, and erase all of > the objects created within the vector. > I thought of using delete operator for each element in the vector, but > what if some other elements has been added from a reference. delete > &something ## failure. > > I guess there is no way to distinguish between object address created > with new and created with a reference. > How a to write a proper destructor then?? There are two points that you must consider. First you must distinguish between object on the heap and objects that are global variables or on the stack (local variables). What you have created with new resides on the heap and must be deleted. Objects on the stack are deleted when the scope is left. Objects in global variables are deletet on program termination. So you cannot add theOrange' address to the basket. You could do it, if you somehow indicate that it is an heap object or not. You could add an flag that could be read during basket destruction. <dirty hack> That's dirty, but you can identify stack, heap and global objects by their address. But that is not portable between compilers and/or operating system and o/s versions. So you should not use it. </dirty hack> Further you could add a pointer to an object, that is already in the basket. This case has not been shown in your sample code. If you cannot avoid this, you need something like a reference counting. Simple to implement, ugly to use. BTW: You wrote about reference and I assume you meen adding the same object to the basket again. C++ references are not an additional pointer to the same object, but a language construct. Regards, Helge -- [ See http://www.gotw.ca/resources/clcm.htm for info about ] [ comp.lang.c++.moderated. First time posters: Do this! ]
|
Pages: 1 Prev: Perfect forwarding of default constructor? Next: Constant Time std::vector Item Removal |