As you can see that operator+ is returning an object of class type MyString.
The assignment operator is not accepting this object in Visual Studio 2019 and giving an error of E0349 that no operands matches. But, in Visual Studio 2012, it is running fine.
Code:
#include <iostream>
using namespace std;
class MyString {
private:
char* str;
int length;
public:
MyString();
MyString(const MyString&);
bool operator!();
friend ostream& operator<<(ostream&, MyString&);
friend istream& operator>>(istream&, MyString&);
MyString& operator=(const MyString&);
MyString operator+(MyString&);
MyString& operator-(MyString);
MyString& operator ++ ();
MyString& operator -- ();
bool operator<(MyString&);
char& operator[](int);
char* operator()(int, int);
void my_strcpy(char*&, char*);
int my_strlen(char*);
};
MyString::MyString() {
str = new char[1];
str[0] = '\0';
length = 0;
}
MyString::MyString(const MyString& obj) {
int size = my_strlen(obj.str) + 1;
str = new char[size];
cout << "copy constructor called\n";
my_strcpy(str, obj.str);
}
bool MyString::operator!() {
if (str[0] == '\0')
return true;
return false;
}
ostream& operator<<(ostream& output, MyString& obj) {
output << obj.str;
return output;
}
istream& operator>>(istream& input, MyString& obj) {
delete obj.str;
obj.str = new char[50];
input.getline(obj.str, 50);
return input;
}
MyString& MyString::operator=(const MyString& obj) {
if (this != &obj) {
my_strcpy(str, obj.str);
}
return *this;
}
char& MyString::operator[](int index) {
if (index >= 0 && index < my_strlen(str))
return str[index];
else {
clog << "Index is out of range\n", exit(1);
}
}
void MyString::my_strcpy(char*& destination, char* source) {
int len_des = my_strlen(destination);
int len_source = my_strlen(source);
delete[]destination;
destination = new char[len_source + 1];
int index = 0;
while (source[index] != '\0')
destination[index] = source[index++];
destination[index] = '\0';
}
MyString MyString::operator+(MyString& obj) {
MyString newObj;
int size = my_strlen(str) + my_strlen(obj.str) + 1;
newObj.str = new char[size];
char* temp = newObj.str;
int index_str = 0;
while (str[index_str] != '\0')
*newObj.str++ = str[index_str++];
index_str = 0;
while (obj.str[index_str] != '\0')
*newObj.str++ = obj.str[index_str++];
*newObj.str = '\0';
newObj.str = temp;
cout << newObj.str << endl;
return newObj;
}
MyString& MyString::operator ++ () {
int size = my_strlen(str) + 2;
char* new_str = new char[size];
char* temp = new_str;
int index = 0;
while (str[index] != '\0')
*new_str++ = str[index++];
*new_str++ = 'a';
*new_str = '\0';
delete[]str;
str = temp;
return *this;
}
MyString& MyString::operator -- () {
int size = my_strlen(str);
char* new_str = new char[size];
char* temp = new_str;
int index = 0;
while (index < size - 1)
*new_str++ = str[index++];
*new_str = '\0';
delete[]str;
str = temp;
return *this;
}
MyString& MyString::operator-(MyString obj) {
bool find = true;
int obj_str_len = my_strlen(obj.str);
int str_len = my_strlen(str);
int start_ind = 0, end_ind = 0;
if (str_len > obj_str_len) {
for (int i = 0; str[i] != '\0'; i++) {
if (str[i] == obj.str[0]) {
start_ind = i;
find = true;
for (int j = i + 1, k = 1; obj.str[k] != '\0' && find; j++, k++) {
if (str[j] != obj.str[k]) {
find = false;
}
end_ind = j + 1;
}
if (find)
break;
}
}
if (find) {
while (str[end_ind] != '\0') {
str[start_ind++] = str[end_ind++];
}
str[str_len - (end_ind - start_ind)] = '\0';
}
}
return *this;
}
bool MyString::operator<(MyString& obj) {
if (my_strlen(str) < my_strlen(obj.str))
return true;
else if (my_strlen(str) > my_strlen(obj.str))
return false;
for (int i = 0; str[i] != '\0'; i++) {
if (str[i] < obj.str[i])
return true;
else if (str[i] > obj.str[i]) {
return false;
}
}
return false;
}
char* MyString::operator()(int starting_index, int ending_index) {
int new_str_size = ending_index - starting_index + 2;
char* new_str = new char[new_str_size];
char* temp = new_str;
int index = 0;
int str_len = my_strlen(str);
while (starting_index < str_len && index < 10)
*new_str++ = str[starting_index++], index++;
*new_str = '\0';
return temp;
}
int MyString::my_strlen(char* str) {
int size = 0;
while (str[size] != '\0')
size++;
return size;
}
int main() {
MyString str1, str2, str3, str4, str6;
if (!str1)
{
cout << "String 1 is Empty.\n";
cout << "Str 1 = " << str1 << endl << endl << endl;
}
cout << "Enter String 1:\t";
cin >> str1;
cout << "Enter String 2:\t";
cin >> str2;
cout << "\n\n\nUser Entered:\n";
cout << "String 1 = " << str1 << endl;
cout << "String 2 = " << str2 << endl << endl << endl;
cout << "Before str1 = str1; str1 = " << str1 << endl;
str1 = str1;
cout << "After str1 = str1, str1 = " << str1 << endl << endl << endl;
cout << "Before str4 = str3 = str1+str2\n";
cout << "str1 = " << str1 << endl;
cout << "str2 = " << str2 << endl;
cout << "str3 = " << str3 << endl;
cout << "str4 = " << str4 << endl;
str4 = str3 = str1 + str2;
cout << "\n\n\nAfter str4 = str3 = str1+str2\n";
cout << "str1 = " << str1 << endl;
cout << "str2 = " << str2 << endl;
cout << "str3 = " << str3 << endl;
cout << "str4 = " << str4 << endl;
cout << "\n\n\nEnter String 3:\t";
cin >> str3;
cout << "\n\n\nEnter String 4:\t";
cin >> str4;
cout << "\n\n\nstr3 = " << str3 << endl;
cout << "str4 = " << str4 << endl;
if (str3 < str4)
cout << "String 3 is Less than String 4.\n";
else
cout << "String 3 is NOT Less than String 4.\n";
MyString str5 = str1 + str2;;
cout << "\n\n\nStr5:\t" << str5 << endl;
cout << "Str5[7]:\t" << str5[7] << endl;
str5[7] = '$';
cout << "\n\nStr5:\t" << str5 << endl;
cout << "\n\n\nstr5(5, 10):\t" << str5(5, 10) << endl;
cout << "\n\n ++Str3 :\t" << ++str3 << endl;
str5 = str4 - str3;
cout << "\n\n Str4 - Str3 :\t" << str5 << endl;
cout << "\n\n --Str3 :\t" << --str3 << endl;
cout << "\n\n --Str3 :\t" << --str3 << endl;
str5 = str4 - str3;
cout << "\n\n Str4 - str3 :\t" << str5 << endl;
return 0;
}
Problem:
The lines str3 = str1 + str2;
and MyString str4 = str1 + str2;
will give an error that no operands matches. This error starts from Visual Studio 2019 and onwards versions.
But, when I use const
in both copy constructor and assignment operator (such as MyString(const MyString&);
MyString& operator=(const MyString&);
), both lines (str3 = str1 + str2; MyString str4 = str1 + str2;
) looks fine to compiler.
But if I Write str3 = str1;
and MyString str4 = str2;
now there is no need to write const
in the copy constructor and assignment operator.
Why is the compiler showing this behaviour.?