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

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

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

Восстановить пароль
Повторная активизация e-mail

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

Ответ
 
Опции темы Поиск в этой теме
Старый 12.12.2012, 21:05   #1
WebbMan
Форумчанин
 
Регистрация: 16.01.2011
Сообщений: 168
По умолчанию Почему при перегруженных = и +, вызывается...

Почему при перегруженных = и +, сразу после отработки +(перегр.), вызывается деструктор, и =(перегр.) уже ничего не получает, за код не ругайте потом все мелочи будут исправляться, главное узнать причину почему деструктор сразу вызывается после A + B
Вот код:
Код:
#include <iostream>

class LongNumber
{
	public:
	char * str_numb;
	bool znak;
	int Cmp(char *, char *);
	char * Plus(char *, char *);
	char * Sub(char *, char *);
	public:
	LongNumber();
	LongNumber(char *);
	LongNumber(char *, bool);
	~LongNumber();
	LongNumber operator =(const LongNumber &);
	LongNumber operator +(const LongNumber &);
	//LongNumber operator -(const LongNumber &);
	//LongNumber operator *(const LongNumber &);
	//LongNumber operator /(const LongNumber &);

};

LongNumber::LongNumber(char * numb)
{
   if(numb[0] == '-')
   {
	 znak = true;
	 str_numb = (char *)malloc( sizeof(char) * strlen(numb)-1 );
	 strcpy(str_numb, &numb[1]);
   }
   else
   {
	 znak = false;
	 str_numb = (char *)malloc( sizeof(char) * strlen(numb) );
	 strcpy(str_numb, numb);
   }
   
}

LongNumber::LongNumber(char * numb, bool zn) //zn - знак
{
	str_numb = numb;
	znak = zn;
}

LongNumber::~LongNumber()
{
	free(str_numb);
}

LongNumber::LongNumber()
{
	str_numb = NULL;
}


int LongNumber::Cmp(char * numb1, char * numb2)
{
	 if( strlen(numb1) > strlen(numb2) )
	 {
		return 1;
	 }
	 else if ( strlen(numb2) > strlen(numb1) )
		  {
			 return 2;
		  }
		  else
		  {

			 for(unsigned int i = 0; i < strlen(numb1); i++ )
			 {
				if( numb1[i]-'0' > numb2[i]-'0' )
				{
				   return 1;
				}
				else if ( numb1[i]-'0' < numb2[i]-'0' )
					 {
					   return 2;
					 }
			 }

		  }

		  return 0;
}




char * LongNumber::Plus(char * numb1, char * numb2)
{

	int sizeN2 = strlen(numb2); int sizeN1 = strlen(numb1);
	int N; char * Number_1, * Number_2;
	if(sizeN2 > sizeN1)
	{
		Number_1 = (char *)malloc(sizeof(char)*sizeN2+1);
		Number_2 = (char *)malloc(sizeof(char)*sizeN2+1);
		strcpy(Number_2, numb2);
		for(int i = 0; i < sizeN2 - sizeN1; i++)
		{
			Number_1[i] = '0';
		}
		for(int i = 0; i < sizeN1; i++)
		{
			Number_1[i + sizeN2 - sizeN1] = numb1[i];
		}
		N = sizeN2;
	}
	else
	{
		Number_1 = (char *)malloc(sizeof(char)*sizeN1+1);
		Number_2 = (char *)malloc(sizeof(char)*sizeN1+1);
		strcpy(Number_1, numb1);
		for(int i = 0; i < sizeN1 - sizeN2; i++)
		{
			Number_2[i] = '0';
		}
		for(int i = 0; i < sizeN2; i++)
		{
			Number_2[i + sizeN1 - sizeN2] = numb2[i];
		}
		N = sizeN1;
	}


	char * numb3 = (char *)malloc(sizeof(char)*(N+1+2));
	memset (numb3, '0', N+1);

	numb3[N+1] = 0;
    int prom = 0; char Prom_number[2];

	while(N - 1 >= 0)
	{
		

	  prom =  Number_2[N-1]-'0' + Number_1[N-1]-'0' + prom;

		if( (prom / 10) == 0  )
		{
		  itoa( prom, Prom_number, 10 );
		  numb3[N] = Prom_number[0];
		  prom = 0;
		}
		else {
			  itoa ( (prom % 10), Prom_number, 10 );
			  numb3[N] = Prom_number[0];

			  prom = ( prom / 10 );
			 }
		N = N - 1;
	}


	itoa ( prom, Prom_number, 10 );
	numb3[0] = Prom_number[0];
	free(Number_1);
	free(Number_2);

	return numb3;
}



LongNumber LongNumber::operator =(const LongNumber &obj)
{
  if(this == &obj)
  return *this;
  if(this->str_numb != NULL)
	free(this->str_numb);
  this->str_numb = (char *)malloc( sizeof(char) * strlen(obj.str_numb) );
  strcpy(this->str_numb, obj.str_numb);
  this->znak = obj.znak;
  return *this;
}

LongNumber LongNumber::operator +(const LongNumber &obj)
{
  if(this->znak == obj.znak)
  {
	LongNumber ret_obj(Plus(this->str_numb, obj.str_numb), this->znak);
	return ret_obj;
  }
  else
  {
	if( Cmp(obj.str_numb, this->str_numb) == 0)
	{
		LongNumber ret_obj("0");
		return ret_obj;
	}

	if( (this->znak == true) && Cmp(obj.str_numb, this->str_numb) == 1 )
	{
		LongNumber ret_obj(Sub(obj.str_numb, this->str_numb), false);
		return ret_obj;
	}
	if( (this->znak == false) && Cmp(obj.str_numb, this->str_numb) == 2)
	{
		LongNumber ret_obj(Sub(this->str_numb, obj.str_numb), false);
		return ret_obj;
	}

	if( (this->znak == true) && Cmp(obj.str_numb, this->str_numb) == 2)
	{
		LongNumber ret_obj(Sub(this->str_numb, obj.str_numb), true);
		return ret_obj;
	}
	if( (this->znak == false) && Cmp(obj.str_numb, this->str_numb) == 1)
	{
		LongNumber ret_obj(Sub(obj.str_numb, this->str_numb), true);
		return ret_obj;
	}


  }
}



int main()
{
	using namespace std;
	LongNumber A("123999"), B("43546"), C;
	C = A + B;
	cout << C.str_numb << endl;

   // C = A - B;
	//cout << C.str_numb << endl;

	return 0;
}
WebbMan вне форума Ответить с цитированием
Старый 12.12.2012, 21:13   #2
WebbMan
Форумчанин
 
Регистрация: 16.01.2011
Сообщений: 168
По умолчанию

И почему то на билдере работает на vs2012 не работает.
WebbMan вне форума Ответить с цитированием
Старый 12.12.2012, 21:14   #3
Perchik71
С++, Delphi
Форумчанин
 
Аватар для Perchik71
 
Регистрация: 24.11.2012
Сообщений: 495
По умолчанию

При вызовах оператора = + - * / оператор должен создать и вернуть новую копию.... лишь при += -= /= *= возвращают ссылку(не указатель) на this.

к примеру

Код:
const TData operator=(int value)
{
TData data;
data.val = value;
return data;
}

const TData& operator+=(int value)
{
val += value;
return *this;
}
при других случая могут возникнуть проблемы ибо...

a = v + c + u; будет жопа.
Если помог, тут весы есть , Вам не сложно, а мне приятно.
Perchik71 вне форума Ответить с цитированием
Старый 12.12.2012, 21:19   #4
Perchik71
С++, Delphi
Форумчанин
 
Аватар для Perchik71
 
Регистрация: 24.11.2012
Сообщений: 495
По умолчанию

Цитата:
Сообщение от WebbMan Посмотреть сообщение
И почему то на билдере работает на vs2012 не работает.
скорее всего проект тот как бы debug режиме, тогда память сохряняется в release должны быть траблы.

///---------

Код:
const LongNumber LongNumber::operator =(const LongNumber &obj)
{
LongNumber t;  
t.str_numb = (char *)malloc(sizeof(char) * (strlen(obj.str_numb) + 1)); // 1 что бы поместить /0
strcpy(t.str_numb, obj.str_numb);
t.znak = obj.znak;
return t;
}
Если помог, тут весы есть , Вам не сложно, а мне приятно.

Последний раз редактировалось Perchik71; 12.12.2012 в 21:31.
Perchik71 вне форума Ответить с цитированием
Старый 12.12.2012, 21:44   #5
_Bers
Старожил
 
Регистрация: 16.12.2011
Сообщений: 2,329
По умолчанию

Цитата:
Сообщение от Perchik71 Посмотреть сообщение
При вызовах оператора = + - * / оператор должен создать и вернуть новую копию.... лишь при += -= /= *= возвращают ссылку(не указатель) на this.

к примеру

Код:
const TData operator=(int value)
{
TData data;
data.val = value;
return data;
}

const TData& operator+=(int value)
{
val += value;
return *this;
}
при других случая могут возникнуть проблемы ибо...

a = v + c + u; будет жопа.
Ничего он не должен. Православные всегда возвращают ссылку
_Bers вне форума Ответить с цитированием
Старый 12.12.2012, 21:48   #6
Perchik71
С++, Delphi
Форумчанин
 
Аватар для Perchik71
 
Регистрация: 24.11.2012
Сообщений: 495
По умолчанию )

Когда ты научишься писать код... который работает в любом случаи... вместо оскорблений мм?
Если помог, тут весы есть , Вам не сложно, а мне приятно.
Perchik71 вне форума Ответить с цитированием
Старый 12.12.2012, 21:48   #7
WebbMan
Форумчанин
 
Регистрация: 16.01.2011
Сообщений: 168
По умолчанию

Цитата:
При вызовах оператора = + - * / оператор должен создать и вернуть новую копию.... лишь при += -= /= *= возвращают ссылку(не указатель) на this.
вы не поняли, я имел ввиду что С = (выполняется A + B возвращаю результат, сразу вызывается деструктор и при выполнении =, уже = справа просто передается очищенный объект), в билдере всё работает, но при трассировке в ВС явно видно как вначале вызывается деструктор после операции + после чего уже оператору = справа передается очищенный объект.

Цитата:
t.str_numb = (char *)malloc(sizeof(char) * (strlen(obj.str_numb) + 1)); // 1 что бы поместить /0
да у меня это исправлено т.к. VS указывал на crt.
WebbMan вне форума Ответить с цитированием
Старый 12.12.2012, 21:57   #8
Perchik71
С++, Delphi
Форумчанин
 
Аватар для Perchik71
 
Регистрация: 24.11.2012
Сообщений: 495
По умолчанию

Цитата:
Сообщение от WebbMan Посмотреть сообщение
вы не поняли, я имел ввиду что С = (выполняется A + B возвращаю результат, сразу вызывается деструктор и при выполнении =, уже = справа просто передается очищенный объект), в билдере всё работает, но при трассировке в ВС явно видно как вначале вызывается деструктор после операции + после чего уже оператору = справа передается очищенный объект.
a = b

вызывается обычно создание нового объекта а потом конструктор копий.... об этом писал сам янг... поэтому, дабы избежать лишнего a(b), будет существенно быстрее..... я поглядел на код... и мне лично думается что деструктор вызываеться как бы на автомате.... это свойсво компиляторов... видимо в вс сначала уничтожаеться создаёться новый.. а потом уже и копия.
Если помог, тут весы есть , Вам не сложно, а мне приятно.
Perchik71 вне форума Ответить с цитированием
Старый 12.12.2012, 22:07   #9
_Bers
Старожил
 
Регистрация: 16.12.2011
Сообщений: 2,329
По умолчанию

Цитата:
Сообщение от Perchik71 Посмотреть сообщение
a = b

вызывается обычно создание нового объекта а потом конструктор копий.... об этом писал сам янг...
Здесь одно из двух:
1. Вызов копирующего конструктора.
2. Вызов оператора=

Если речь идет об оператор=, то нужны особые причины, что бы не возвращать ссылку.

Создавать новый объект, уповая на RVO/NRVO без особой необходимости - признак непрофессионала. Поскольку не контролируемо, когда эти оптимизации откажут
_Bers вне форума Ответить с цитированием
Старый 12.12.2012, 22:19   #10
Perchik71
С++, Delphi
Форумчанин
 
Аватар для Perchik71
 
Регистрация: 24.11.2012
Сообщений: 495
По умолчанию

Bers, напиши книгу в 100 000 экзепляров.... диктуй и читай свои мысли миллионам людей....

Кстати = должно подрузомивать такую стратегию.... ибо объект уничтожается.... ты хоть застрелись... this уже уничтожен.

нужен новый объект..

конструктор копий вызывается либо в операторе = или как фуна...

//-----

ссылка TTipe&
указатель TTipe*

в моём примере ссылка не нужна.. ибо делается новый объект....
в += ссылку нужна... ибо мы изменяем содержимое... A += D += H; в си нельзя писать.. и это безопасно.
Если помог, тут весы есть , Вам не сложно, а мне приятно.

Последний раз редактировалось Perchik71; 12.12.2012 в 22:21.
Perchik71 вне форума Ответить с цитированием
Ответ


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



Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Почему вызывается деструктор? MrGukk Общие вопросы C/C++ 13 23.08.2012 17:42
перегруженных функций..???? /*Oleh*/ Общие вопросы C/C++ 2 20.02.2011 01:36
Приведение процедурных типов в перегруженных методах AndreyCo Общие вопросы Delphi 8 10.11.2009 19:20
Как отловить события которое вызывается при розворачивании подменющек (PopupMenu) DarkEvil Общие вопросы Delphi 9 09.05.2009 18:17
Почему ошибка при копировании? valerij Microsoft Office Excel 8 02.05.2009 01:49