Форум программистов, компьютерный форум CyberForum.ru

Объясните про инициализацию - C++

Восстановить пароль Регистрация
 
Merovingian
54 / 54 / 5
Регистрация: 24.09.2011
Сообщений: 149
19.02.2012, 17:56     Объясните про инициализацию #1
Реализовал свой класс для строки (в качестве практики изучения c++)

это не так важно

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
class TString
{
    char* p;
    int size;
public:
    TString(){ size = 0; p = NULL; };
    TString(const char*);
    TString(const TString&);
    ~TString(){if(p) delete [] p;};
    TString& operator=(const TString);
    int length(){ return size;}
    friend ostream& operator<<(ostream&, TString);
};

Класс самый обычный, реализация методов не так важна... Есть следующие строчки в main():

Tstring s("Hello world!");
Tsring s1 = s;
s = s1;
s1 = "Hello!";

Какие методы должны вызываться в каждой строчке?
Tstring s("Hello world!") - вызывается TString(const char* s)
Tsring s1 = s - вызывается TString(const TString& s)
s = s1 - вызывается TString(const TString& s)
s1 = "Hello!" - вызывается TString(const char* s) а за ним в след TString& operator=(const TString);

Интересует последняя строчка, почему идёт два вызова?
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
19.02.2012, 17:56     Объясните про инициализацию
Посмотрите здесь:

C++ розшифруйте инициализацию словами
C++ Объясните про наследование
1.про функция exit(); 2.про this C++
Включение, как правильно сделать инициализацию C++
Объясните про strchr C++
После регистрации реклама в сообщениях будет скрыта и будут доступны все возможности форума.
OstapBender
 Аватар для OstapBender
581 / 519 / 35
Регистрация: 22.03.2011
Сообщений: 1,585
19.02.2012, 18:02     Объясните про инициализацию #2
Merovingian, сделай TString& operator=(const char*);
и будет тебе 1 вызов
silent_1991
Эксперт C++
4938 / 3014 / 149
Регистрация: 11.11.2009
Сообщений: 7,024
Завершенные тесты: 1
19.02.2012, 18:20     Объясните про инициализацию #3
Цитата Сообщение от Merovingian Посмотреть сообщение
s = s1 - вызывается TString(const TString& s)
Как так? О_о Должен оператор присваивания вызываться.
go
Эксперт C++
3582 / 1362 / 128
Регистрация: 16.04.2009
Сообщений: 4,528
19.02.2012, 18:26     Объясните про инициализацию #4
Цитата Сообщение от Merovingian Посмотреть сообщение
s1 = "Hello!";
Вызывается оператор присваивания. Чтобы разобраться в этом, добавь везде печать.
Merovingian
54 / 54 / 5
Регистрация: 24.09.2011
Сообщений: 149
19.02.2012, 18:26  [ТС]     Объясните про инициализацию #5
Цитата Сообщение от OstapBender Посмотреть сообщение
Merovingian, сделай TString& operator=(const char*);
и будет тебе 1 вызов
сделать дополнительно еще метод или изменить TString& operator=(const TStrint&) на TString& operator=(const char*)
??
silent_1991
Эксперт C++
4938 / 3014 / 149
Регистрация: 11.11.2009
Сообщений: 7,024
Завершенные тесты: 1
19.02.2012, 18:28     Объясните про инициализацию #6
Цитата Сообщение от Merovingian Посмотреть сообщение
Интересует последняя строчка, почему идёт два вызова?
Выше сказали, как исправить, ну а я скажу, почему именно два:
Конструктор с одним параметром, не объявленный как explicit, служит оператором преобразования типа из типа параметра конструктора в тип класса. У вас именно такой конструктор имеется, принимающий константную строку. Таким образом, он является оператором преобразования из const char * в TString. Но чтобы присвоить одну строку другой, нужно вызвать оператор присваивания. А у вас имеется только один оператор присваивания, принимающий константную ссылку на TString. Однако также имеется оператор пользовательского преобразования, преобразующий константную строку в TString. Значит присвоить константную строку объекту типа TString можно посредством преобразования этой строки в TString, а этим занимается конструктор. Строка
C++
1
s1 = "Hello!";
по сути разворачивается в
C++
1
s1 = TString("hello");
, а затем в
C++
1
s1.operator=(TString("Hello!"));
. Вот и два вызова. Если вы реализуете оператор присваивания, принимающий const char *, то вызов конструктора для создания временного объекта не потребуется, и буде только вызов operator=.

Добавлено через 1 минуту
Цитата Сообщение от Merovingian Посмотреть сообщение
сделать дополнительно еще метод
Именно.

Цитата Сообщение от Merovingian Посмотреть сообщение
изменить TString& operator=(const TStrint&) на TString& operator=(const char*)
А вот в этом случае вы не сможете инициализировать свою строку другим объектом типа TString. Хоть компилятору и известно о преобразовании const char * -> TString посредством конструктора с параметром, но об обратном преобразовании он ничего не знает. А такой оператор присваивания, который не может присвоить одному объекту другой объект того же типа, нафиг не нужен))
Merovingian
54 / 54 / 5
Регистрация: 24.09.2011
Сообщений: 149
19.02.2012, 18:32  [ТС]     Объясните про инициализацию #7
Цитата Сообщение от silent_1991 Посмотреть сообщение
Как так? О_о Должен оператор присваивания вызываться.
Сам в шоке! Действительно так. Ладно попробую сделать везде печать и понаблюдать что происходит.

Тогда такой вопрос:
C++
1
2
3
4
5
6
TString();
TString(const char*);
TString(const TString&);
~TString(){if(p) delete [] p;};
TString& operator=(const TString&);
TString& operator=(const char*);
Этого будет достаточно?
silent_1991
Эксперт C++
4938 / 3014 / 149
Регистрация: 11.11.2009
Сообщений: 7,024
Завершенные тесты: 1
19.02.2012, 18:34     Объясните про инициализацию #8
Цитата Сообщение от Merovingian Посмотреть сообщение
Сам в шоке! Действительно так
"Не верю!" (с)

Цитата Сообщение от Merovingian Посмотреть сообщение
Этого будет достаточно?
Я бы ещё позволил одиночный символ присваивать.
go
Эксперт C++
3582 / 1362 / 128
Регистрация: 16.04.2009
Сообщений: 4,528
19.02.2012, 18:36     Объясните про инициализацию #9
Цитата Сообщение от silent_1991 Посмотреть сообщение
Как так? Должен оператор присваивания вызываться.
http://liveworkspace.org/code/5e1854...c1484a50534123
silent_1991
Эксперт C++
4938 / 3014 / 149
Регистрация: 11.11.2009
Сообщений: 7,024
Завершенные тесты: 1
19.02.2012, 18:37     Объясните про инициализацию #10
go, не понял, это опровержение или подтверждение?
Merovingian
54 / 54 / 5
Регистрация: 24.09.2011
Сообщений: 149
19.02.2012, 18:40  [ТС]     Объясните про инициализацию #11
silent_1991, Спасибо за подробное объяснение!!!

Не по теме:

Немножко мозги закипают. Раньше писал и не задумывался, например зачем по ссылке передавать в конструктор копирования и как то обходился)))

silent_1991
Эксперт C++
4938 / 3014 / 149
Регистрация: 11.11.2009
Сообщений: 7,024
Завершенные тесты: 1
19.02.2012, 18:44     Объясните про инициализацию #12
Merovingian, да, в С++ очень много подобных тонкостей. И, что странно, меньше их со временем не становится...
go
Эксперт C++
3582 / 1362 / 128
Регистрация: 16.04.2009
Сообщений: 4,528
19.02.2012, 18:47     Объясните про инициализацию #13
Цитата Сообщение от silent_1991 Посмотреть сообщение
s1 = "Hello!";
по сути разворачивается в
Код C++
1
s1 = TString("hello");
, а затем в
Код C++
1
s1.operator=(TString("Hello!"));
http://liveworkspace.org/code/dfe1dd...7f4b7f946f606f
Что Вы здесь имели ввиду?

Добавлено через 50 секунд
Цитата Сообщение от go Посмотреть сообщение
s1.operator=(TString("Hello!"));
obj operator= (const char *_s) ?

Добавлено через 30 секунд
Цитата Сообщение от Merovingian Посмотреть сообщение
TString& operator=(const TString);
Этого не заметил
silent_1991
Эксперт C++
4938 / 3014 / 149
Регистрация: 11.11.2009
Сообщений: 7,024
Завершенные тесты: 1
19.02.2012, 18:49     Объясните про инициализацию #14
go,
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
class TString
{
        char* p;
        int size;
public:
        TString(){ size = 0; p = NULL; };
        TString(const char*);
        TString(const TString&);
        ~TString(){if(p) delete [] p;};
        TString& operator=(const TString);
        int length(){ return size;}
        friend ostream& operator<<(ostream&, TString);
};
Где?

Добавлено через 47 секунд
Кстааати, я тоже не заметил. По ссылке передавать надо!

Добавлено через 52 секунды
А, ну ясно, просто опечатка.

Цитата Сообщение от go Посмотреть сообщение
Этого не заметил
Не поэтому вызывается конструктор с параметром.
go
Эксперт C++
3582 / 1362 / 128
Регистрация: 16.04.2009
Сообщений: 4,528
19.02.2012, 18:50     Объясните про инициализацию #15
Как бы я не про то спрашивал. Вы правы.
Цитата Сообщение от silent_1991 Посмотреть сообщение
Не поэтому вызывается конструктор с параметромю
В смысле? Сравните.
http://liveworkspace.org/code/48a4eb...d1049f0d7f6996
http://liveworkspace.org/code/dfe1dd...7f4b7f946f606f
silent_1991
Эксперт C++
4938 / 3014 / 149
Регистрация: 11.11.2009
Сообщений: 7,024
Завершенные тесты: 1
19.02.2012, 18:53     Объясните про инициализацию #16
go, конструктор вызывается не потому, что объект передаётся по значению (мне показалось, ты именно об этом говорил), а потому, что нет оператора присваивания, принимающего const char *.
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
19.02.2012, 18:54     Объясните про инициализацию
Еще ссылки по теме:

Добавить инициализацию и удаление в приведенный код C++
Объясните задачу про представление вещественных чисел в памяти компьютера C++
Популярно объясните про указатели C++

Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
go
19.02.2012, 18:54     Объясните про инициализацию
  #17

Не по теме:

Цитата Сообщение от silent_1991 Посмотреть сообщение
go, конструктор вызывается не потому, что объект передаётся по значению (мне показалось, ты именно об этом говорил), а потому, что нет оператора присваивания, принимающего const char *.
Я тоже про это. Но видно, меня опять не поняли

Yandex
Объявления
19.02.2012, 18:54     Объясните про инициализацию
Ответ Создать тему
Опции темы

Текущее время: 02:53. Часовой пояс GMT +3.
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2016, vBulletin Solutions, Inc.
Рейтинг@Mail.ru