LinuxQuestions.org
Help answer threads with 0 replies.
Home Forums Tutorials Articles Register
Go Back   LinuxQuestions.org > Forums > Non-*NIX Forums > Programming
User Name
Password
Programming This forum is for all programming questions.
The question does not have to be directly related to Linux and any language is fair game.

Notices


Reply
  Search this Thread
Old 06-23-2012, 06:42 AM   #1
grob115
Member
 
Registered: Oct 2005
Posts: 542

Rep: Reputation: 32
Unable to add object to STL map


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);

};
main.cpp
Code:
typedef std::map<std::string, SpcialClass> mapReferenceName_SpcialClass;
mapReferenceName_SpcialClass map_ReferenceName_SpcialClass;

SpcialClass specialClassObject;
map_ReferenceName_SpcialClass.insert(std::pair<std::string, SpcialClass>(ReferenceName, specialClassObject));
Compiler Error
Code:
error: ‘SpcialClass::SpcialClass(const SpcialClass&)’ is private

Last edited by grob115; 06-23-2012 at 06:56 AM.
 
Old 06-23-2012, 07:08 AM   #2
dwhitney67
Senior Member
 
Registered: Jun 2006
Location: Maryland
Distribution: Kubuntu, Fedora, RHEL
Posts: 1,541

Rep: Reputation: 335Reputation: 335Reputation: 335Reputation: 335
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:
Code:
typedef std::map<std::string, SpcialClass*> mapReferenceName_SpcialClass;
 
Old 06-23-2012, 09:35 AM   #3
grob115
Member
 
Registered: Oct 2005
Posts: 542

Original Poster
Rep: Reputation: 32
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?
 
Old 06-23-2012, 12:32 PM   #4
dwhitney67
Senior Member
 
Registered: Jun 2006
Location: Maryland
Distribution: Kubuntu, Fedora, RHEL
Posts: 1,541

Rep: Reputation: 335Reputation: 335Reputation: 335Reputation: 335
Quote:
Originally Posted by grob115 View Post
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.
 
Old 06-24-2012, 07:39 AM   #5
grob115
Member
 
Registered: Oct 2005
Posts: 542

Original Poster
Rep: Reputation: 32
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
Code:
#include <iostream>
#include <algorithm>
 
class Array {
public:
    int size;
    int* data;
 
    explicit Array(int size) 
        : size(size), data(new int[size])
    {
    }
    Array(const Array& other)
        : size(other.size), data(new int[other.size]) 
    {
        std::copy(other.data, other.data + other.size, data); 
    }
 
    ~Array() 
    {
        delete[] this->data;
    }
};
 
int main() 
{
    Array first(20);
    first.data[0] = 25;
 
    {
        Array copy = first;
        std::cout << first.data[0] << " " << copy.data[0] << std::endl;
    }    
 
    first.data[0] = 10;
}

Last edited by grob115; 06-24-2012 at 08:43 AM.
 
Old 06-24-2012, 07:44 AM   #6
dwhitney67
Senior Member
 
Registered: Jun 2006
Location: Maryland
Distribution: Kubuntu, Fedora, RHEL
Posts: 1,541

Rep: Reputation: 335Reputation: 335Reputation: 335Reputation: 335
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.
 
Old 06-24-2012, 09:47 AM   #7
grob115
Member
 
Registered: Oct 2005
Posts: 542

Original Poster
Rep: Reputation: 32
Quote:
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?
 
Old 06-24-2012, 10:25 AM   #8
grob115
Member
 
Registered: Oct 2005
Posts: 542

Original Poster
Rep: Reputation: 32
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.h
Code:
class ContainerClass {
public:
    ContainerClass(std::string name);
    virtual ~ContainerClass();
    std::string name;

    void initialize();
private:
    SpecialClass SpecialClassObject;
};

ContainerClass.cpp
Code:
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();
}

Last edited by grob115; 06-24-2012 at 10:29 AM.
 
Old 06-24-2012, 10:27 AM   #9
ta0kira
Senior Member
 
Registered: Sep 2004
Distribution: FreeBSD 9.1, Kubuntu 12.10
Posts: 3,078

Rep: Reputation: Disabled
Quote:
Originally Posted by grob115 View Post
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
 
Old 06-24-2012, 10:56 AM   #10
grob115
Member
 
Registered: Oct 2005
Posts: 542

Original Poster
Rep: Reputation: 32
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.
 
  


Reply



Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is Off
HTML code is Off



Similar Threads
Thread Thread Starter Forum Replies Last Post
DNS 'unable to add reverse map': timed out g@z Linux - Networking 5 12-29-2011 05:53 AM
Unable to add forward map connection refused aleksandarotasevic Linux - Newbie 2 05-20-2010 11:54 PM
dhcpd - Unable to add forward map from host.domain.org elvisious Linux - Software 1 03-09-2009 07:57 AM
Unable to add forward map durwin Linux - Networking 0 06-26-2005 03:20 PM
Event driven object-to-object: C++ template class mecanism ( NOT STL or STDC++) bretzeltux Programming 2 12-23-2003 02:45 PM

LinuxQuestions.org > Forums > Non-*NIX Forums > Programming

All times are GMT -5. The time now is 08:17 PM.

Main Menu
Advertisement
My LQ
Write for LQ
LinuxQuestions.org is looking for people interested in writing Editorials, Articles, Reviews, and more. If you'd like to contribute content, let us know.
Main Menu
Syndicate
RSS1  Latest Threads
RSS1  LQ News
Twitter: @linuxquestions
Open Source Consulting | Domain Registration