I have a class say,
class Foo
{
public:
void ProcessString(std::string &buffer)
{
// perform operations on std::string
// call other functions within class
// which use same std::string string
}
void Bar(std::string &buffer)
{
// perform other operations on "std::string" buffer
}
void Baz(std::string &buffer)
{
// perform other operations on "std::string" buffer
}
};
This class tries to use a std::string
buffer to perform operations on it using various methods under these conditions:
std::string
which I already have.For example:
// Once an object is created
Foo myObject;
// We could pass many different std::string's to same method without copying
std::string s1, s2, s3;
myObject.ProcessString(s1);
myObject.ProcessString(s2);
myObject.ProcessString(s3);
I could use the string and assign it as a class member so that other functions using can know about it.
But it seems we cannot have a reference class member std::string &buffer
because it can only be initialized from constructor.
I could use a pointer to std::string
i.e. std::string *buffer
and use it as a class member and then pass the addresses of s1, s2, s3
.
class Foo
{
public:
void ProcessString(std::string *buf)
{
// Save pointer
buffer = buf;
// perform operations on std::string
// call other functions within class
// which use same std::string string
}
void Bar()
{
// perform other operations on "std::string" buffer
}
void Baz()
{
// perform other operations on "std::string" buffer
}
private:
std::string *buffer;
};
Or, the other way could be pass each functions a reference to std::string
buffer just as shown in the first example above.
Both ways kind of seem a bit ugly workarounds to be able to use a std::string
without copying as I have rarely seen the usage of std::string as a pointer or pass all the functions of class the same argument.
Is there a better around this or what I'm doing is just fine?
std::string object will allocate internal buffer and will copy the string pointed to by ps there. Changes to that string will not be reflected to the ps buffer, and vice versa. It's called "deep copy".
There is no functionality difference between string and std::string because they're the same type. That said, there are times where you would prefer std::string over string .
Use std::string when you need to store a value. Use const char * when you want maximum flexibility, as almost everything can be easily converted to or from one. Save this answer.
C-strings are usually faster, because they do not call malloc/new. But there are cases where std::string is faster. Function strlen() is O(N), but std::string::size() is O(1). Also when you search for substring, in C strings you need to check for '\0' on every cycle, in std::string - you don't.
Keeping in MyObject a reference or a pointer to a string which is not ownned by your object is dangerous. It will be easy to get nasty undefined behaviour.
Look at the following legal example (Bar is public):
myObject.ProcessString(s1); // start with s1 and keep its address
myObject.Bar(); // works with s1 (using address previously stored)
Look at the following UB:
if (is_today) {
myObject.ProcessString(string("Hello")); // uses an automatic temporary string
} // !! end of block: temporary is destroyed!
else {
string tmp = to_string(1234); // create a block variable
myObject.ProcessString(tmp); // call the main function
} // !! end of block: tmp is destroyed
myObject.Bar(); // expects to work with pointer, but in reality use an object that was already destroyed !! => UB
The errors are very nasty, because when reading function's usage, everything seems ok and well managed. The problem is hidden by automatic destruction of bloc variables.
So if you really want to avoid the copy of the string, you could use a pointer as you envisaged, but you shall only use this pointer in functions called directly by ProcessString(), and make these functions private.
In all other case, I'd strongly suggest to reconsider your position, and envisage:
string&
parameters in all the object's function that need it. This avoids the copies but leaves to caller the responsibility of organising the proper management of the string. If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With