Форум программистов
 

Восстановите пароль или Зарегистрируйтесь на форуме, о проблемах и с заказом рекламы пишите сюда - alarforum@yandex.ru, проверяйте папку спам!

Вернуться   Форум программистов > C/C++ программирование > Общие вопросы C/C++
Регистрация

Восстановить пароль

Купить рекламу на форуме - 42 тыс руб за месяц

Ответ
 
Опции темы Поиск в этой теме
Старый 17.09.2012, 11:55   #11
waleri
Старожил
 
Регистрация: 13.07.2012
Сообщений: 6,372
По умолчанию

А вы выделяете память для data а потом *меняете* указатель. в С++ строки не копируются автомагически (для этого вы и пишете String клас). В конструкторе, после выделения памяти воспользуйтесь услугами strcpy()
waleri вне форума Ответить с цитированием
Старый 17.09.2012, 15:19   #12
sidestep
Пользователь
 
Регистрация: 14.09.2011
Сообщений: 93
По умолчанию

так я и делал

Есть подозрение, что деструктор работает неправильно, так как в программе объект копируется местами, т.е. один объект копируется к другому и когда запускается деструктор запускается для того и того - т.е. фактически запускается дважды
sidestep вне форума Ответить с цитированием
Старый 17.09.2012, 15:30   #13
sidestep
Пользователь
 
Регистрация: 14.09.2011
Сообщений: 93
По умолчанию

Весь код
Код:
#include <stdlib.h>
#include <string.h>
#include <conio.h>
#include <iostream>

using namespace std;

class String 
{
private: 
	char* data;
public:
	String () 
	{
		// конструктор по умолчанию (создает пустую строку)
		data = new char[1];
		data = "";
	}
	String (char* my_stroka) 
	{ 
		// конструктор с параметром
		data = new char[strlen(my_stroka) + 1];
		strcpy(data, my_stroka);
	}
	String (String& my_Str) 
	{
		// конструктор копирования (в качестве параметра передается ссылка на существующий объект)
		int len = strlen(my_Str.data);
		if (len) 
		{
			data = new char[len + 1];
			strcpy(data, my_Str.data);
		} 
		else 
		{
			data = new char[1];
			data = "";
		}
	}
	
	~String () 
	{
	// деструктор
	delete[] data;
	}
	
	void display () const // const - значит, что функция не меняет объект
	{
		cout << data << endl;
	}

	String  operator+ (String) const;    // перегрузка оператора "+" для объектов класса String
	void    operator+= (String);   // перегрузка оператора "+="
	String& operator= (const String&);   // перегрузка оператора присваивания, так как присваивается неизменная строчка

	char  operator[] (int) const;   // перегрузка оператора [] для просто чтения по заданному индексу (int) const - значит после
	char& operator[] (int);     // перегрузка оператора [], с возвращением значения по ссылке, для изменения значения
	// символа, с данным индексом
	operator char* () const // выводит дату
	{
		return data;
	}
};

String String::operator+ (String str2) const 
{
	char* concat = new char[strlen(data) + strlen(str2.data) + 1];
	strcpy(concat, data);
	strcat(concat, str2.data);
	return String(concat); // запускаем конструктор с одним аргументом
	/* strcpy - копирует data в concat
	* strcpy - прибавляет к concat строчку str2.data (поэтому и создается дополнительная строчка
	* concat, а не прибавляем сразу к data, так как иначе бы изменилась сама data)
	*/
}

void String::operator+= (String str2) 
{
	strcat(data, str2.data); // к дате прибавляет 2ю строчку
}

String& String::operator= (const String& str2)  
{
	// короче в c++ достаточно специфичный случай для равенства объектов obj = obj, поэтому его надо "обойти"
	if(this != &str2) //this - ссылка на объект данного класса
	{
		char* copybaby = new char[strlen(str2.data) + 1];
		strcpy(copybaby, str2.data);
		//delete[] data;
		data = copybaby;
	}
	return *this; // указатель на объект, поэтому разименовываем this и выводим
}

char String::operator[] (int my_index) const 
{
	if (my_index < 0 || my_index >= strlen(data)) 
	{
		cout << "\n govno, a ne index" << endl;
	}
	else 
	{
		return data[my_index];
	}
}

char& String::operator[] (int my_index) 
{
	if (my_index < 0 || my_index >= strlen(data)) 
	{
		cout << "\ngovno, a ne index" << endl;
	} 
	else 
	{
		return *(data + my_index); // выводим ссылку, data - указывает на первый элемент
	}
}

int main() 
{
	String str1; // пустая строка, используется конструктор по умолчанию
	String str2 = "Privet!"; // используется конструктор с одним параметром
	String str3("Dobrui Den!"); // также используется конструктор с одним параметром 
	String str4 = str2; // конструктор копирования
	String str5(str3);  // конструктор копирования
	
	//----------------------------
	cout << "proverka rabotu konstruktorov:" << endl;
	str1.display();
	str2.display();
	str3.display();
	str4.display();
	str5.display();
	//----------------------------

	//----------------------------
	cout << "\nproverka operatora privideniya k tipu \"char\": " << endl;
	cout << "data obiekta str2 = ";
	str2.display();
	char* gavnoCHAROVSKOE = str2;
	cout << "peremenaya gavnoCHAROVSKOE posle prispoeniya znacheniya str2 = " << gavnoCHAROVSKOE << endl;
	//----------------------------

	//----------------------------
	cout << "\nproverka rabotu operatora prisvaivania:" << endl;
	str2.display();
	str5.display();
	cout << "teper prisvaivaem str2 = str5..." << endl;
	str2 = str5;
	str2.display();
	str5.display();
	//----------------------------

	//----------------------------
	cout << "\nproverka rabotu operetora\"+\":";
	str1 = "\nPrepod, ";
	str4 = str1 + str3;
	str4.display();
	//----------------------------

	//----------------------------
	cout << "\nproverka rabotu operatora\"+=\": ";
	str2 = "Zdarova!";
	str1 += str2;
	str1.display();
	//----------------------------

	//----------------------------
	cout << "\nproverka rabotu operatora\"[]\": ";
	str1.display();
	cout << "zadaite index" << endl;
	int index;
	cin >> index;
	cout << str1[index];


	cout << "\n\nteper menat budem\n";
	cout << "zadaite index: ";
	cin >> index;
	cout << "zadaite novoe znachenie: ";
	char value;
	cin >> value;
	str1[index] = value;
	str1.display();
	//----------------------------

	getch();
	return 0;
}

Т.е. так как мы там копировали, то деструктор вызывается дважды

Как обойти этот момент?
sidestep вне форума Ответить с цитированием
Старый 17.09.2012, 17:12   #14
waleri
Старожил
 
Регистрация: 13.07.2012
Сообщений: 6,372
По умолчанию

У вас все написано в operator=, правда почему то закоментировано удаление старой памяти. При создании пустой строки вы теряете указатель на выделенную память. При операторе + то же самое: выделяте память, потом вызываете к конструктор а он делает то же самое опять. Когда вы возвращаете String (как например в operator +) вызывается copy constructor - у вас его нет. Вы думаете он есть но он написан неправильно, соответственно компилятор генерит свой.
waleri вне форума Ответить с цитированием
Старый 17.09.2012, 17:54   #15
sidestep
Пользователь
 
Регистрация: 14.09.2011
Сообщений: 93
По умолчанию

все равно ошибка, даже если я комментарии уберу
sidestep вне форума Ответить с цитированием
Старый 20.09.2012, 18:34   #16
sidestep
Пользователь
 
Регистрация: 14.09.2011
Сообщений: 93
По умолчанию

ребят надо помочь исправить - срочно!
sidestep вне форума Ответить с цитированием
Старый 20.09.2012, 19:46   #17
monolit111
Пользователь
 
Регистрация: 14.09.2011
Сообщений: 95
По умолчанию

Кстати, конструктор копирования с const пишется..Иначе это не совсем тот конструктор копирования, который подразумевался)
monolit111 вне форума Ответить с цитированием
Старый 20.09.2012, 19:57   #18
sidestep
Пользователь
 
Регистрация: 14.09.2011
Сообщений: 93
По умолчанию

деструктор !!!!
sidestep вне форума Ответить с цитированием
Старый 20.09.2012, 20:03   #19
_-Re@l-_
C++, Java
Старожил
 
Аватар для _-Re@l-_
 
Регистрация: 10.04.2010
Сообщений: 2,665
По умолчанию

Цитата:
Время жмет, его мало - горит оценка, это важно тоже.
Вот нам в универе задали написать виртуальную машину, попутно изучив JScript и придумав свой язык программирования(для которого и реализовывается ВМ), и всё это за неделю, вот это я понимаю, время поджимает. А помимо этого предмета ещё десяток. А у вас, халява просто
_-Re@l-_ вне форума Ответить с цитированием
Старый 20.09.2012, 20:54   #20
sidestep
Пользователь
 
Регистрация: 14.09.2011
Сообщений: 93
По умолчанию

В чем ошибка, поставлю так вопрос ?

почему это копирование должно быть const ?
sidestep вне форума Ответить с цитированием
Ответ


Купить рекламу на форуме - 42 тыс руб за месяц



Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
сТРОКИ ООП С++ Camom1Le Помощь студентам 0 30.11.2010 21:55
C++ ООП Smile.id Помощь студентам 2 21.02.2010 13:41
ООП AlekDruzh Паскаль, Turbo Pascal, PascalABC.NET 0 09.09.2009 20:32
Паскаль ООП. Примеры программ с использованием ООП SeЯgey Помощь студентам 5 13.05.2009 21:55