I wrote my own string class for learning purposes. I'm trying to overload the += operator so that I can append strings together. But whenever I use the operator the inital object remains the same. I am confused.
StringF& StringF::operator+=(StringF& obj) {
const char* string = this->getString();
const char* stringToAppend = obj.getString();
const int stringLength = this->length();
const int stringToAppendLength = obj.length();
char* appendedString = new char[stringLength + stringToAppendLength];
appendedString[stringLength + stringToAppendLength] = '\0';
for (int i = 0; i < stringLength; i++) {
appendedString[i] = string[i];
}
for (int i = stringLength; i < stringLength + stringToAppendLength; i++) {
appendedString[i] = stringToAppend[i - stringLength];
}
StringF appendedObj = StringF::StringF(appendedString);
std::cout << "Appended obj: " << appendedObj.getString() << std::endl; //For debugging
return appendedObj;
}
Here is the class header file:
class StringF {
private:
const char* string;
public:
StringF(const char*);
int length();
const char* copy();
const char* getString();
const char* reverse();
int find(const char*);
StringF& operator+=(StringF&);
friend std::ostream& operator<<(std::ostream&, StringF&);
};
I want to be able to create two strings and append with one another. But the it doesn't work. Any ideas? If possible, I'd want an explanation as to why this doesn't work so I can try to figure it out on my own, as I am trying to learn I don't want the solution handed to me. But I'll take whatever.
So here is what I'm trying to do.
StringF s("Hello");
StringF s2(", World!");
s += s2;
std::cout << s << std::endl; //Should print "Hello, World!" but only prints "Hello".
Thanks in advance!
Edit: Here is the example for you to try. https://onlinegdb.com/ApfkIONXG
There are a few issues with the code as posted:
this
instance like operator+=
is supposed toHere is some minimally edited code that fixes these issues
StringF& StringF::operator+=(StringF& obj) {
const char* stringToAppend = obj.getString();
const int stringLength = this->length();
const int stringToAppendLength = obj.length();
// +1 for the null character we are appending
char* appendedString = new char[stringLength + stringToAppendLength + 1];
appendedString[stringLength + stringToAppendLength] = '\0';
for (int i = 0; i < stringLength; i++) {
appendedString[i] = string[i];
}
for (int i = stringLength; i < stringLength + stringToAppendLength; i++) {
appendedString[i] = stringToAppend[i - stringLength];
}
// TODO: de-allocate the previous 'string' member variable
// Now we need to update `this`. While we can't modify the data pointed
// at by the existing member pointer, we can change the pointer to point
// to the newly allocated data:
string = appendedString;
// operator+= should be returning a reference to `this`
return *this;
}
We can modify the member variable because const char*
is a mutable pointer to constant characters. This means the characters at the address of the pointer are constant, but the memory storing the pointer address is still mutable.
|string: 0xDEADBEEF| // The pointer value is not const
|
|----> |abc\0| // This data is const
see Why are both "const T" and "T const" valid, and which one should you use? for more info on the const
issue.
The return *this
is because the general expectation of operator+=
is that the following code should work:
StringF s1("a");
StringF s2("b");
StringF s3 = (s += s2);
assert(s3 == s);
This might seem like non-sense code in this simple example, but this pattern is useful in some cases and is the expected behavior of a operator+=
overload.