Добрый день!
Нужно создать класс (строка, завершающаяся терминальным нулём) и перегрузить операции «+» (конкатенация строк) и «[]» (вставка символа). С этими задачами я справился без труда, и пришло время заняться созданием деструктора. И тут понеслось...
Суть в том, что когда начинает работать процедура перегрузки операции «+», у меня создаётся дополнительная переменная k, в которую копируется первая строка, а затем при помощи strcat
добавляется вторая. И, казалось бы, всё хорошо, но как только дело доходит до return
, деструктор подчищает переменную k и возвращает... ну, возвращает всякую ерунду.
Не то чтобы я удивлён этим событием, я прекрасно понимаю, почему это происходит, но никак не могу решить эту проблему. Подскажите, как я могу исправить этот косяк.
Собственно говоря, код:
#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(A.n + B.n);
strcpy(k.s, A.s); //Копируем 1-ую строку в новую
strcat(k.s, B.s); //Вставляем 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;
}
Для начала, у вас неправильный оператор сложения. Он возвращает ссылку на экземпляр класса в стеке. Это плохо, потому что по выходу из функции его стек умирает. Переделайте функцию, чтобы она возвращала не ссылку, а копию объекта.
Далее, вам понадобится конструктор копирования (знаете, что это такое?). Дело в том, что при возвращении класса из функции локальная переменная копируется в результат при помощи этого самого конструктора. Поскольку у вас конструктор не определён, используется конструктор по умолчанию, который копирует все поля, в частности, "мёртвый" указатель.
Итого:
stroka operator + (const stroka& A, const stroka& B);
stroka(const stroka& A);
Кстати, правило «большой тройки» рекомендует сделать деструктор виртуальным, и добавить оператор присваивания.
Кофе для программистов: как напиток влияет на продуктивность кодеров?
Рекламные вывески: как привлечь внимание и увеличить продажи
Стратегії та тренди в SMM - Технології, що формують майбутнє сьогодні
Выделенный сервер, что это, для чего нужен и какие характеристики важны?
Современные решения для бизнеса: как облачные и виртуальные технологии меняют рынок
нахожу среднее арифметическое всех элементов двумерно массива но почему-то значение округлется, а мне нужно чтобы выдавало что то вроде...