Good day!

It is necessary to create a class (a line ending with a terminal zero) and reload the operations “+” (string concatenation) and “[]” (insert a character). I coped with these tasks without difficulty, and it was time to start creating a destructor. And then it started ...

The bottom line is that when the “+” operation overload procedure starts, I create an additional variable k into which the first line is copied, and then the second one is added using strcat . And, it would seem, everything is fine, but as soon as it comes to return , the destructor cleans up the variable k and returns ... well, returns nonsense.

Not that I'm surprised by this event, I understand perfectly why this is happening, but I just can not solve this problem. Tell me how I can fix this joint.

Actually, the code:

 #define _CRT_SECURE_NO_WARNINGS #include "stdafx.h" #include <iostream> #include <conio.h> #include <math.h> #include <string.h> #include <stdio.h> class stroka { private: char* s; int n; public: stroka(); //Конструктор по умолчанию stroka(int n1); //Конструктор с параметром void input(); //Функция ввода строки void output(); //Функция вывода строки на экран friend stroka& operator + (stroka& A, stroka& B); char& operator [] (int p) { return s[p]; } ~stroka(void); }; stroka::~stroka(void) { std::cout << "Очистка памяти" << std::endl; delete[] s; } stroka::stroka() { s = new char[1]; *s = 0; n = 0; } stroka::stroka(int n1) { s = new char[n1]; n = n1; } void stroka::input() { std::cout << "Введите строку: "; std::cin.getline(s, n, '\n'); } void stroka::output() { std::cout << "Введённая строка: " << s << std::endl << std::endl; } stroka& operator + (stroka& A, stroka& B) { stroka k(An + Bn); strcpy(ks, As); //Копируем 1-ую строку в новую strcat(ks, Bs); //Вставляем 2-ую строку в конец новой return k; } int _tmain(int argc, _TCHAR* argv[]) { setlocale(0, "Rus"); stroka A(10); stroka B(10); A.input(); //Ввод строки A.output(); //Вывод строки B.input(); B.output(); stroka C = A + B; C.output(); int pos; //Позиция вставки std::cout << "Номер позиции вставки элемента: "; std::cin >> pos; std::cout << "Введите элемент: "; char symbol; //Вставляемый символ std::cin >> symbol; C[pos] = symbol; C.output(); std::cout << endl << "Хорошего дня!"; _getch(); return 0; } 

    1 answer 1

    For starters, you have the wrong addition operator. It returns a reference to an instance of the class in the stack. This is bad, because on leaving the function, its stack dies. Redo the function so that it returns not a link, but a copy of the object.

    Next, you need a copy constructor (know what it is?). The fact is that when a class returns from a function, the local variable is copied to the result using this same constructor. Since your constructor is undefined, the default constructor is used, which copies all fields, in particular, the "dead" pointer.

    Total:

     stroka operator + (const stroka& A, const stroka& B); stroka(const stroka& A); 

    By the way, the rule of the " big three " recommends that you make the destructor virtual, and add an assignment operator.

    • Well, you directly downloaded me, I do not have time to google for you. Let's take it in order: 1) As for the first remark: well, it seems I understood everything, I don’t even know why I shoved the link. - xeeqqw
    • 2) The copy constructor is probably the only item that I did not understand. You wrote: “The fact is that when a class returns from a function, the local variable is copied into the result with the help of this constructor itself” - is it just about return k? I did not quite understand where the default constructor you are talking about is called. I already called the constructor with the parameters: stroka k (A.n + Bn) ... and now I just need to return k back to main. How and where should the copy constructor work? - xeeqqw
    • 3) I read about the virtual destructor and it seems to be needed, if the derived class is used, I don’t have it. Well, in any case, is this something like this:? virtual ~ stroka (void); - xeeqqw
    • 2) The copy constructor is called implicitly by the string return k : the object k copied to the return value of the function. 3) Basically, you are right: in this example, the destructor virtuality is optional. It is rather a good tone, in case you inherit from this class. Simply write virtual , yes. - VladD
    • 2
      No, no, you should allocate more memory for the string, and not forget about n : stroka :: stroka (const stroka & A) {n = An; s = new char [n + 1]; strcpy (s, as); } By the way, sizeof returns not at all what you think: the size of the pointer , not the string . - VladD