Reputation: 3370
I have a class whose constructor takes a const reference to a string. This string acts as the name of the object and therefore is needed throughout the lifetime of an instance of the class.
Now imagine how one could use this class:
class myclass {
public:
myclass(const std::string& _name) : name(_name) {}
private:
std::string name;
};
myclass* proc() {
std::string str("hello");
myclass* instance = new myclass(str);
//...
return instance;
}
int main() {
myclass* inst = proc();
//...
delete inst;
return 0;
}
As the string in proc() is created on the stack and therefore is deleted when proc() finishes, what happens with my reference to it inside the class instance? My guess is that it becomes invalid. Would I be better off to keep a copy inside the class? I just want to avoid any unneccessary copying of potentially big objects like a string...
Upvotes: 2
Views: 7587
Reputation: 12942
Keep a copy of the string in MyClass, keeping a reference is definitively not safe. If you expect a lot of instances to have the same name, you should look into the Flyweight design pattern which allows to save storage when you have a lot of equal instances. Boost.Flyweight is a very conventient implementation of this pattern that allows you to simply write:
class myclass {
public:
myclass(const std::string& _name) : name(_name) {}
private:
boost::flyweight<std::string> name;
};
Some implementations of std::string may do this behind the scene, but it is not required. You should therefor not rely on this.
Upvotes: 0
Reputation: 1424
Yes the std::string will disappear but the c str "hello" will not as it is a constant.
You have two possible answers. Use the c str as a reference or make the std:string a staic.
Upvotes: 1
Reputation: 35490
Yes, Reference becomes invalid in your case. Since you are using the string it is better to keep a copy of the string object in myclass
class.
Upvotes: 8
Reputation: 2865
The field myclass::name should be of type std::string. Strings in C++ are copied-on-write (http://en.wikipedia.org/wiki/Copy-on-write) so you don't get problems with copying of big objects.
Upvotes: 0
Reputation: 143279
You don't have to do copying. Declare std::string name
(not reference) member in myclass
(which you somehow omitted altogether). and pass const char *
as an argument. This way you will construct your name object right in the class with no copying.
class myclass {
public:
std::string name;
myclass(const char *_name) : name(_name) { }
};
myclass *proc() {
return new myclass("hello");
}
Upvotes: 1
Reputation: 3176
If myclass::_name is not a reference then it is copied and will not become invalid.
Upvotes: 1
Reputation: 14392
By all means: copy. Have a "std::string name" member in your class. It's the only way to control the life-time.
Upvotes: 3