Оператор присваивания

Модераторы: Hawk, Romeo, Absurd, DeeJayC, WinMain

Lotles
Сообщения: 59
Зарегистрирован: 03 июл 2010, 12:42

Объясните как работает эта прога чо то я запутался

Код: Выделить всё

#include "stdafx.h"
#include "conio.h"
#include <string.h>
using namespace std;
int a;
class String {
private:
    char* ptr;
	char* ptr1;
public:
	String(){
		ptr = new char[1];
        ptr[0] = '\0';
	}
	String(char* s){
		    int n = strlen(s);
            ptr = new char[n + 1];
            strcpy(ptr, s);
	}
	String(const String& src){ 
		cout << "Vizivaetsja konstruction " << endl;
		    int n = strlen(src.ptr);
            ptr = new char[n + 1];
            strcpy(ptr, src.ptr);
	}

	~String(){
		    delete [] ptr;
	}

    String& operator=(const String& src){
		cout << "Vizivaetsja operator prisvaivanija" << endl;
		cout << "src.ptr = " << src.ptr << endl;
		cout << "src.ptr1 = " << src.ptr1 << endl;
		cpy(src.ptr); 
		return *this;
	}



	String operator+(char* s){
		cout << "Vizivaetsja operator+" << endl;
		String new_str(ptr);
			cout << "S = " << s << endl;
			cout << "new_str.ptr = " << new_str.ptr << endl;
			cout << "ptr = " << ptr << endl;
            new_str.cat(s);
            return new_str;
	}
    operator char*() {
		cout << "vizvalsja operator char*" << endl;
		cout << "ptr = " << ptr << endl;
		return ptr;
	}
	void cat(char* s){
		    int n = strlen(ptr) + strlen(s);
			cout <<".......... " << ptr << endl;
			cout <<".......... " << s << endl;
            char* p1 = new char[n + 1];
            strcpy(p1, ptr);
            strcat(p1, s);
            delete [] ptr;
            ptr = p1;
	}
	void cpy(char* s){
		delete [] ptr;
        int n = strlen(s);
        ptr = new char[n + 1];
        strcpy(ptr, s);
	}
};

int main() {
    String a, b, c;
    a = "I ";
    b = "am ";
    c = "so ";
    String d = a + b + c;
    cout << d;
	cout << endl;
    return 0;
}
например когда выполняется эта строка

Код: Выделить всё

a = "I ";
я думаю должен запускаться

Код: Выделить всё

String operator=(const char*){
...
}
у меня в классе его нету, компилятор создает свой
напр

Код: Выделить всё

String operator=(const char*){
...
}
и что дальше, а может вообще не так происходит
ПОМОГИТЕ !
Просто в учебнике вообще по тупорылому все объясняется, не понятно и поверхностно
BulldozerBSG
Сообщения: 270
Зарегистрирован: 09 янв 2010, 04:14
Контактная информация:

зато есть конструктор, где в качестве параметра передается char * вот он и используется.
BBB
Сообщения: 1298
Зарегистрирован: 27 дек 2005, 13:37

BulldozerBSG писал(а):зато есть конструктор, где в качестве параметра передается char * вот он и используется.
Т.е., первый шаг - создается временный объекта String с помощью, как написал BulldozerBSG, конструктора String(char* s). А второй шаг - вызывается оператор присвоения String& operator=(const String& src)
Lotles
Сообщения: 59
Зарегистрирован: 03 июл 2010, 12:42

С этим разобрался просто трудно было понять потому что думал что код как бы идет слева на право тогда получается что сначало идет оператор присваивания и оттуда вся путаница

Вот еще вопос

Здесь создается временный объект

Код: Выделить всё

    String(char* s){
            int n = strlen(s);
            ptr = new char[n + 1];
            strcpy(ptr, s);
Как определить где точно он удаляется

И еще
Вот здесь

Код: Выделить всё

    void cpy(char* s){
        delete [] ptr;
        int n = strlen(s);
        ptr = new char[n + 1];
        strcpy(ptr, s);
    }
тоже временный объект создается или нет, если нет тогда в ptr какого объекта копируется S
azrael
Сообщения: 89
Зарегистрирован: 31 май 2009, 15:30
Контактная информация:

Никаких временных объектов тут нет, тут есть выделение памяти и сохранение указателя на эту память внутри объекта класса String.
Память выделяется там, где new (new[]), освобождается там, где для указателя вызывается delete (delete []).
s копируется не в ptr (т.к. это указатель), а в память, на которую смотрит этот указатель.
Lotles
Сообщения: 59
Зарегистрирован: 03 июл 2010, 12:42

azrael писал(а):Никаких временных объектов тут нет, тут есть выделение памяти и сохранение указателя на эту память внутри объекта класса String.
Память выделяется там, где new (new[]), освобождается там, где для указателя вызывается delete (delete []).
s копируется не в ptr (т.к. это указатель), а в память, на которую смотрит этот указатель.

Допустим это так
Тогда дольше должно быть присваивание

Код: Выделить всё

String& operator=(const String& src){
и в аргументах стоит объект, где он его берет
Lotles
Сообщения: 59
Зарегистрирован: 03 июл 2010, 12:42

azrael писал(а):Никаких временных объектов тут нет, тут есть выделение памяти и сохранение указателя на эту память внутри объекта класса String.
Память выделяется там, где new (new[]), освобождается там, где для указателя вызывается delete (delete []).
s копируется не в ptr (т.к. это указатель), а в память, на которую смотрит этот указатель.

Где Тут
Вобще в программе или в отрывке кода

Код: Выделить всё

  void cpy(char* s){
        delete [] ptr;
        int n = strlen(s);
        ptr = new char[n + 1];
        strcpy(ptr, s);
    }
Lotles
Сообщения: 59
Зарегистрирован: 03 июл 2010, 12:42

Код: Выделить всё

  void cpy(char* s){
        delete [] ptr;
        int n = strlen(s);
        ptr = new char[n + 1];
        strcpy(ptr, s);
    }
Если здесь не создается временный объект то ptr к какому объекту относится
BBB
Сообщения: 1298
Зарегистрирован: 27 дек 2005, 13:37

Временный объект неявнор создается самим компилятором, чтобы он смог сделать присвоение. После выполения оператора присвоения временный объект удаляется.

Т.е. "внутри" происходит примерно следующее.
Оператор a = "I "; неявно "преобразуется" к:

Код: Выделить всё

String *tmp = new String ("I ");
a = *tmp;   // вызывается String& operator=(const String& src) 
delete tmp;
azrael
Сообщения: 89
Зарегистрирован: 31 май 2009, 15:30
Контактная информация:

Lotles писал(а):

Код: Выделить всё

  void cpy(char* s){
        delete [] ptr;
        int n = strlen(s);
        ptr = new char[n + 1];
        strcpy(ptr, s);
    }
Если здесь не создается временный объект то ptr к какому объекту относится

Объект у вас тут уже создан - это объект String. ptr - это поле этого объекта, оно у каждого экземпляра класса String свое. Любой нестатический метод класса (cpy, например) имеет скрытый первый параметр - указатель на объект, на котором надо вызвать метод. По этому указателю и совершаются все действия над объектом, в частности, изменение значений его полей. Т.е. когда вы делаете "ptr = " внутри объекта класса, на самом деле происходит "this->ptr = ", где this - указатель на объект класса String, в котором производятся все действия в методе.

Наверное, немного сумбурно объяснил :)
Закрыто