Other issues with the code is that there is no destructor (memory leak) and no assignment operator function (although not used in the class test code - default does a shallow copy rather than the needed deep copy)...
#include <iostream>
#include <string>
usingnamespace std; //considered problematic and 'bad' but its legal and works.
class Demo
{
string* str; //pointers should be avoided unless studying pointers or no other way to do something.
public:
const string& content() const
{
return *str; //this will fail if str is null or invalid
}
Demo(const string& x)
{
str = new string(x);
}
Demo(Demo&& x)
{
str = x.str;
x.str = nullptr; //this is how the above could fail... and it may leak memory as does the class itself
}
};
int main()
{
Demo demo1("Chiquado");
Demo demo2 = Demo("Chiquado");
cout<<demo1.content()<<" "<<demo2.content()<<endl;
return 0;
Arguably, the onus is on you to not use that function on a moved-from object, just like how you can't dereference a moved-from smart pointer. But that should be properly documented. Certainly would be kinder to not have pre-conditions for calling content(), similar to how you can call c_str() on a moved-from std::string (I think).
What exactly is and isn't valid for a moved-from object is sometimes confusing for me, so maybe somebody else can say what the de facto standard should be.
I still don't know what that means, though. For example, if it's "valid", does that mean that you're allowed to dereference a moved-from std::string's c_str()? Or does "unspecified" mean that c_str() could return any value?
c_str() could return any valid value. Note that for a pointer nullptr is a valid value but obviously can't be dereferenced. A returned non-nullptr valid value would be one that could be referenced or used with delete/delete[]
After something has been 'moved-from' then it's not common practice to refer to it's value. Usually a moved-from pointer is given a value of nullptr so that delete/delete[] will work ok if used.
It's worth noting that the valid-but-unspecified thing is only the case for objects in std. Take a look at n3241: https://wg21.link/n3241
That being said, my understanding is that you can still call c_str and dereference the result, because c_str is specified to always return a NTSB as long as it is called on a valid std::string. If c_str instead returned a null or dangling pointer that would mean the std::string was invalid.
Why use a pointer to a std::string? That eliminates a lot of the automatic memory management a C++ string provides. A C++ string is not a C string, they require different usage and management.
Using a normal C++ string as a data member and std::move is arguably a better utilization of C++.
Note that there is no requirement for different compilers to return the same valid-but-unspecified value! My advice is don't use (except for maybe curiosity) after a moved-from.
Personally I'd treat a moved object to be as safe as an empty elevator shaft on the 40th floor with the doors open. Oooops, if you should absently walk through the doorway.
At the very least MSVC++ flags the use of a moved object as a possible issue.