Reputation: 61
Hello i made a variable storage like string
and this is the source
class str
{
private:
const char * _mystring;
public:
// Using this function to made new str
str(const char * _str) { _mystring = _str; }
// Get the content of this str
const char * read() { return _mystring; }
// Get the content in char *
char * read_c() { return strdup(_mystring); }
// Operator for equal action with extern const char
str & operator = (const char * _str) { _mystring = _str; return *this; }
// Operator for equal action with extern str storage
str & operator = (str _str) { _mystring = _str.read(); return *this; }
// Operator for add action
str operator + (const char * _str) {
return str(strcat(read_c(), _str));
}
// Operator for add action with new str
str operator + (str & _str) {
return str(strcat(read_c(), _str.read()));
}
};
and this is my test program
int main() {
str var1("Var1"); // No problem
str var2("Var2"); // No problem
str var3 = var1 + var2; // No problem
str var4 = var1 + "tempStr"; // I got runtime error !
str var5 = "tempStr" + var2; // I got error before compile
cout << var1.read() << endl;
cout << var2.read() << endl;
cout << var3.read() << endl;
cout << var4.read() << endl;
return 0;
}
what is the problem that i can't create something like var3 and var4 and i got error (i get error while i want to merge const char with my str ... i set + operator but there is problem for when i want to merge const char with my str (not my str with const char... on this action, there is no problem) but wait i got error (debug (close program)) after compile and print var7 too !
Upvotes: 1
Views: 3974
Reputation: 3558
For str var3 = "tempTxt0" + "tempTxt1" + "tempTxt2"; // Error
:
This does not work because the compiler sees these types (omitting variable names): str = const char* + const char* + const char *
. Adding char pointers together is not what you want. However, if you only had one of them to be type of class str
, it would work. E.g. str = str(const char*) + const char* + const char *
would call the str::operator+
, which returns a new object of type str
and the rest will follow the same way.
For str var4 = "tempTxt3" + var1; // Error
:
This does not work because you declare operator+
as a member function. Again compiler sees these types (omitting variable names): str = const char* + str
. There is no operator+
declared for const char*
as the first operand and str
as the second operand. You have a member operator+
but that operator works on a class str
so you would need a class str
on the left hand side; as in str + const char*
. Think of it like a function call because it is exactly a member function call. It is the same as typing str = str.operator+("text")
. Now you see, str = "text".operator+(str)
does not work because it does not exist.
If you declared a non-member function str operator+(const char* first, const str& second);
, it would work. The compiler will look for operators that matches what you want in outer namespace scopes of the parameters up to the global scope (this is called ADL). But there is a better way:
Declare str operator+(const str& lhs, const str& rhs);
. If you declare your operators this way in the namespace scope of the class str
, then compiler will use ADL (on Wikipedia) using the second argument's type (which is class str
) and find this operator. Then, the compiler can see that class str
has a non-explicit constructor which can take const char*
: str(const char * str)
. It can then create a temporary object of class str
and use the operator+
you defined.
So for your example, as you do not have any namespaces, you would need this at its simplest (notice I have added a few const
keywords):
class str
{
private:
const char * _mystring;
public:
// Using this function to made new str
str(const char * _str) { _mystring = _str; }
// Get the content of this str
const char * read() const { return _mystring; }
// Get the content in char *
char * read_c() const { return strdup(_mystring); }
// Operator for equal action with extern const char
str & operator = (const char * _str) { _mystring = _str; return *this; }
// Operator for equal action with extern str storage
str & operator = (str _str) { _mystring = _str.read(); return *this; }
};
// Operator for add action with new str
str operator+ (const str& lhs, const str& rhs) {
return str(strcat(lhs.read_c(), rhs.read()));
}
P.S.
Your example has more problems. read_c
duplicates the string (let say) of 10 bytes and you concatenate more bytes at the end of it. That is an overflow because your duplicated buffer is 10 bytes. You have to allocate and free the memory properly but that is for another question I guess. E.g.
str operator+(const str& lhs, const str& rhs) {
const std::size_t ls = lhs.size();
const std::size_t rs = rhs.size();
char* n = new char[ls + rs + 1];
std::memcpy(n, lhs.read(), ls);
std::memcpy(n + ls, rhs.read(), rs);
n[ls + rs] = '\0';
return str(n);
}
Then you still have the problem of when to delete
.
Upvotes: 3
Reputation: 528
str var3 = "tempTxt0" + "tempTxt1" + "tempTxt2"; // Error
str var4 = "tempTxt3" + var1; // Error
In these lines you're trying to add 2 pointers to some static memory (in other words your operator isn't called)
On the left side of the operator plus needs to be your class
Having an empty (only with \0
) instance of your class will fix your error (as you might have already noted):
str var4 = str("") + "tempTxt3" + var1; //now it is okay
Also, note that strcat
doesn't allocate memory for concatening, you have to do it with realloc
yourself
Upvotes: 3
Reputation: 49986
str var4 = var1 + "tempStr"; // I got runtime error !
in this case following operator+ overload is called:
str operator + (const char * _str) {
return str(strcat(read_c(), _str));
}
you call strcat
on a pointer which points to a buffer not large enough to contain both current string and _str. The fastest solution is to use std::string
, otherwise you need to allocate large enough buffer and also remember to keep care of its lifetime (adhere to rule of three etc.)
str var5 = "tempStr" + var2; // I got error before compile
You need a global operator overload of following signature:
str operator + (const char * _str, const str& s);
Upvotes: 0
Reputation: 223972
When you override a binary operator such as +
, the left operand has to be the object in question. The reason you get errors is because the left operand is a string constant and this the default +
is used.
You need to create friend functions for these operators that accept a const char *
for the first parameter and either str
or a const char *
for the second parameter.
Upvotes: 2