I have the following class:
class StringHolder
{
public:
StringHolder(std::string& str)
{
m_str = &str;
}
private:
std::string* m_str;
};
And have the following string object (str
), with a size of 1,0开发者_Python百科24KB:
char c = 'a';
unsigned long long limit = 1024 * 1024;
std::stringstream stream;
for(int i = 0; i < limit; i++)
{
stream << c;
}
std::string str = stream.str();
Whenever I initialize the StringHolder class with a string, it doesn't make a copy of that string. That's because I used references & pointers, but I'm not sure if I used them properly :\
The question: did I use references & pointers properly?
The correct implementation should be something like
class StringHolder
{
public:
StringHolder(const std::string& str) //note const
: m_str(str){} //use initialization list
private:
std::string m_str; //no need to make it a pointer
};
Under the assumption that the lifetime of the string is known to outlive the object that will refer to it, and that the object will not need to modify the string, then you can take a constant reference to the string in the constructor and store that in:
class StringHolder {
std::string const & str;
public:
StringHolder( std::string const & s ) : str(s) {}
};
With this solution the contents of the string will not be copied, but any change to the original string will affect the contents seen from the reference. Also, this does not allow you to change the string referred to after construction. If you need to reseat the reference you will have to do with a pointer:
class StringHolder {
std::string const * str;
public:
StringHolder( std::string const & s ) : str(&s) {}
void reset( std::string const & s ) {
str = &s;
}
};
The fact that you need to store a pointer instead of a reference is an implementation detail, so you can (as I did) hide it from the user, or you could change the interface to take the string by pointer to make it more explicit (I prefer the former, but the later has the effect of self documentation: it is clearer that lifetimes have to be considered).
Also note that with the implementation as shown, a temporary can be used to initialize/set the string, causing undefined behavior: temporary dies, reference points to nowhere.
精彩评论