tags:

views:

98

answers:

4

i have a STL string member variable in my class,

class A {
public:
   const char* getData1() const { return data.c_str());
   const string& getData2() const { return _data; }
private:
   string _data;
};

getData1() vs. getData2(), which one is better?

+1  A: 

Both are a little dangerous because your object may go out of scope, or its memory may be freed. But you'll still have a pointer or reference to one of its members.

If you really want to do this though, it just depends on if you want access to the string methods or not. Also c_str()'s const char* may be memory that will be freed on you.

If _data is not that big maybe just return a string, not a const string&.

Brian R. Bondy
+4  A: 

The one returning a string reference is the better of the two choices. If the string is changed internally, a previously returned string reference would still be valid, but the const char * probably would not be.

Better than either of those choices may be to just return by value.

std::string getData3() const { return data_; }

Also, I'd suggest not prefixing variables with an underscore, and get rid of that using namespace std; statement.

Dan
Bit of a noob question to ask relating to this. But if you went, say,`std::string s = A.getData2()` where the function returns a reference, would the copy constructor be called?
Duracell
Yes, the copy constructor is called.
Chris Henry
@duracell: ... but strings are allowed to implement copy-on-write (although it's fallen out of favor) in which case the copy constructor only copies the pointers and marks a flag.
Potatoswatter
@Chris: you don't know that. It'd be more correct to say that it is *allowed* for the compiler to call the copy constructor. It is also allowed to eliminate the copy as long as it doesn't affect the outcome of the code (which is why it may be a better option)
jalf
@jalf, you're right. As long as the behavior is the same as if the copy constructor is called then it is fine.
Chris Henry
+1  A: 

Generally I prefer getData2(). The const char* returned by c_str() method can only be used as long as data's non-const methods are not called. After that, the content of const char* is undefined. By returning const char*, you are masking this issue. If the user of the class needs to use a C-style string, he can call c_str() himself on the returned const string&.

Here we are also assuming that the user of getData2() reasonably assumes that the returned reference will only available to him as long as the object of class A is not destroyed yet.

Chris Henry
In terms of efficiency, which one is better?
Do you have a measured performance deficiency? If not, don't worry about which one is more efficient. It's better to worry about which one will not create hard-to-find bugs. If you return a pointer and that pointer becomes invalidated, your program may crash or do strange things. Worry about efficiency later, when your program is working correctly and you want to tweak it to be a bit faster.
Dan
@user342673: which do you think? One calls a member function on the string, and returns the result. The other returns a reference to the string directly. If anything, the string reference is going to be faster for that reason alone.
jalf
A: 

Returning a const string& is better. If you need a const char*, you can just call getData2().c_str() which is practically identical to what getData1() does.

Remember std::strings are better than const char* strings because they store the length, instead of being null terminated. This means if you want to get the length of that string, strlen(getData1()) is an O(n) operation, but getData2().length() is an O(1) operation.

AshleysBrain