ProgrammingThis forum is for all programming questions.
The question does not have to be directly related to Linux and any language is fair game.
Notices
Welcome to LinuxQuestions.org, a friendly and active Linux Community.
You are currently viewing LQ as a guest. By joining our community you will have the ability to post topics, receive our newsletter, use the advanced search, subscribe to threads and access many other special features. Registration is quick, simple and absolutely free. Join our community today!
Note that registered members see fewer ads, and ContentLink is completely disabled once you log in.
If you have any problems with the registration process or your account login, please contact us. If you need to reset your password, click here.
Having a problem logging in? Please visit this page to clear all LQ-related cookies.
Get a virtual cloud desktop with the Linux distro that you want in less than five minutes with Shells! With over 10 pre-installed distros to choose from, the worry-free installation life is here! Whether you are a digital nomad or just looking for flexibility, Shells can put your Linux machine on the device that you want to use.
Exclusive for LQ members, get up to 45% off per month. Click here for more info.
Hi, am not sure why but when I add in the line highlighted in red, I am getting the compiler error printed below about the class is private. While I can see one of the class constructors is defined as private but the way I am instantiating it without arguments should have used the public version, shouldn't it? Any ideas or guidance is much appreciated.
SpecialClass.h
Code:
class SpcialClass : public SpecialClassObjectParent
{
public:
SpcialClass();
virtual ~SpcialClass() {}
private:
SpcialClass(const SpcialClass& specialClass);
};
Your STL map definition is going to require a copy-constructor. I believe you can avoid this requirement if you were to elect to store pointers to your class objects instead of the objects themselves. Something like:
Ah thanks for the pointer. I didn't write the class SpcialClass or its parent class SpecialClassObjectParent. Therefore I don't know how they were implemented. But believe what you are suggesting is that the classes may have pointers as variables, therefore requiring the use of deep copy rather than shallow copy thus the need to have a special copy constructor for my STL map?
Unfortunately using a pointer wouldn't work as one of the reasons I'm using a STL map is because I'm looping through the code block within which I'm instantiating the SpecialClass object. In other words, once the loop is done and the required number of objects are created, the loop block will exit out of scope destroying the objects also.
What I have done to circumvent this in the past is to create a STL map before I enter the loop, and then add the objects instantiated while inside the loop to this STL map. Guess the technique wouldn't work this time around?
Ah thanks for the pointer. I didn't write the class SpcialClass or its parent class SpecialClassObjectParent. Therefore I don't know how they were implemented. But believe what you are suggesting is that the classes may have pointers as variables, therefore requiring the use of deep copy rather than shallow copy thus the need to have a special copy constructor for my STL map?
Unfortunately using a pointer wouldn't work as one of the reasons I'm using a STL map is because I'm looping through the code block within which I'm instantiating the SpecialClass object. In other words, once the loop is done and the required number of objects are created, the loop block will exit out of scope destroying the objects also.
What I have done to circumvent this in the past is to create a STL map before I enter the loop, and then add the objects instantiated while inside the loop to this STL map. Guess the technique wouldn't work this time around?
The scope of an object, whether it be of type Foo or std::map, is relegated to the block of code where it is defined... unless the object is allocated on the heap.
Your reason for not using a pointer is not valid, nor does it make sense. If you allocate an object, it is available anywhere in the program space until it is freed.
For example:
Code:
std::map<int, SpcialClass*> myMap;
for (int i = 0; i < 10; ++i)
{
myMap.insert(std::pair<int, SpcialClass*>(i, new SpcialClass);
}
Last edited by dwhitney67; 06-23-2012 at 12:34 PM.
Reason: Oops... I mixed Java with the C++ syntax.
Hi, okay sorry I was confusing myself. Thought you simply asked me to use pointer to reference the objects within the loop without putting them into the STL map, even though you asked me to! There is a difference between what you are asking me to do versus what I am trying to do. What I'm puzzled is I have written another piece of code that is exactly like the "Not using pointer" case below and yet the objects (not the pointers to the objects) inserted into the STL map lives even after exiting the loop that created them.
Just looked at the copy constructor issue at Wikipedia here, and it appears (I have added the copy constructor highlighted in blue into the code block they used as an example which would have other crashed the program with the line highlighted in red) that the object that lives at the end of the code is the one that was copied from (identified by the variable "first"), not the one that was created (identified by the variable "copy"), because "first" was created before entering the block surrounded by the opening and closing braces. Therefore, in the example you provided with the "new SpecialClass" object created while within the "for loop" and added to the STL map should have been destroyed when the "for loop" exits. Isn't this the case?
Using pointer
Code:
std::map<int, SpcialClass*> myMap;
for (int i = 0; i < 10; ++i)
{
myMap.insert(std::pair<int, SpcialClass*>(i, new SpcialClass);
}
Not using pointer
Code:
std::map<int, SpcialClass> myMap;
for (int i = 0; i < 10; ++i)
{
SpcialClass specialClassObject;
myMap.insert(std::pair<int, SpcialClass>(i, specialClassObject);
}
Wikipedia example of specifying a copy constructor
Your second example, "Not using pointer", will only work if the std::map is able to make a copy of the SpcialClass object you created; hence the need to have a copy-constructor for SpcialClass.
If the SpcialClass class is complex, calling the copy-constructor can be inefficient versus merely storing a pointer to an object. I hope this much is clear.
If the SpcialClass class is complex, calling the copy-constructor can be inefficient versus merely storing a pointer to an object. I hope this much is clear.
But if the object was created in a loop, it'd be destroyed as soon as it exits from the loop even if a pointer to it has been created and stored in a map, wouldn't it?
Tried also using a container class as described in this tutorial. But as soon as type in something as asked by the block of code highlighted in pink, whatever it is being done by SpecialClassObject.action() is stopped. Any ideas? I thought by having a separate class to hold the "SpecialClassObject" created would work as long as the "ContainerClassObject" object is still in scope within the main() function. Apparently this isn't the case either. Any ideas?
SpecialClass.h
Code:
class SpecialClass : public SpecialClassObjectParent {
public:
SpecialClass();
virtual ~SpecialClass() {}
void action();
private:
SpecialClass(const SpecialClass& specialClass);
};
ContainerClass::ContainerClass(std::string name) {
// default constructor initializes the class to hold SpecialClassObject
this->name = name;
}
void ContainerClass::initialize() {
SpecialClassObject.action();
std::string input;
std::cout << "Please type some input before continuing:\n";
std::cin >> input;
}
Code:
main() {
std::string name = "first";
ContainerClass ContainerClassObject(name);
ContainerClassObject.initialize();
}
But if the object was created in a loop, it'd be destroyed as soon as it exits from the loop even if a pointer to it has been created and stored in a map, wouldn't it?
You're missing the call to new in dwhitney67's example code. When control reaches the end of the loop it unwinds the stack back to the beginning of the loop; that doesn't mean it undoes every constructor call made in the loop. When you use new the object is created on the heap, which means it won't be automatically destructed; this is why there's a delete operator. Such objects will exist until you call delete to destruct and deallocate them.
Kevin Barry
Ah great thanks. This is good info.
And BTW, I just run some additional tests against the container class above. The SpecialClassObject created by ContainerClassObject still exists. Not sure why SpecialClassObject.action() stops working. Need to do some investigation on this.
But yes the stack vs heap explanation was great. Thanks. Will give it a try.
LinuxQuestions.org is looking for people interested in writing
Editorials, Articles, Reviews, and more. If you'd like to contribute
content, let us know.