Форум программистов, компьютерный форум, киберфорум
С++ для начинающих
Войти
Регистрация
Восстановить пароль
 
Рейтинг 4.60/5: Рейтинг темы: голосов - 5, средняя оценка - 4.60
54 / 54 / 9
Регистрация: 24.09.2011
Сообщений: 149
1

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

19.02.2012, 17:56. Показов 934. Ответов 16
Метки нет (Все метки)

Реализовал свой класс для строки (в качестве практики изучения 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);

Интересует последняя строчка, почему идёт два вызова?
0
Programming
Эксперт
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
19.02.2012, 17:56
Ответы с готовыми решениями:

Про позднюю инициализацию std::thread
Я занимаюсь проигрыванием MIDI-файлов. В общем: есть мультимедиа-таймер, который каждую...

Про инициализацию объекта в поле класса
Извините за тупой вопрос. Но,почему нельзя инициализировать объект в поле класса? у меня есть...

Объясните про strchr
pch-str+1 - 1).что это значит? Координально не понятно, ведь строкой выше, а именно...

Объясните про исключения
Собственно хочу реализовать класс исключений. Начал искать информацию в интернете, но там были в...

__________________

Записывайтесь на профессиональные курсы C++ разработчиков
16
591 / 529 / 76
Регистрация: 22.03.2011
Сообщений: 1,585
19.02.2012, 18:02 2
Merovingian, сделай TString& operator=(const char*);
и будет тебе 1 вызов
1
Эксперт С++
5042 / 3103 / 271
Регистрация: 11.11.2009
Сообщений: 7,047
19.02.2012, 18:20 3
Цитата Сообщение от Merovingian Посмотреть сообщение
s = s1 - вызывается TString(const TString& s)
Как так? О_о Должен оператор присваивания вызываться.
0
go
Эксперт С++
3643 / 1375 / 243
Регистрация: 16.04.2009
Сообщений: 4,527
19.02.2012, 18:26 4
Цитата Сообщение от Merovingian Посмотреть сообщение
s1 = "Hello!";
Вызывается оператор присваивания. Чтобы разобраться в этом, добавь везде печать.
1
54 / 54 / 9
Регистрация: 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*)
??
0
Эксперт С++
5042 / 3103 / 271
Регистрация: 11.11.2009
Сообщений: 7,047
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 посредством конструктора с параметром, но об обратном преобразовании он ничего не знает. А такой оператор присваивания, который не может присвоить одному объекту другой объект того же типа, нафиг не нужен))
2
54 / 54 / 9
Регистрация: 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*);
Этого будет достаточно?
0
Эксперт С++
5042 / 3103 / 271
Регистрация: 11.11.2009
Сообщений: 7,047
19.02.2012, 18:34 8
Цитата Сообщение от Merovingian Посмотреть сообщение
Сам в шоке! Действительно так
"Не верю!" (с)

Цитата Сообщение от Merovingian Посмотреть сообщение
Этого будет достаточно?
Я бы ещё позволил одиночный символ присваивать.
0
go
Эксперт С++
3643 / 1375 / 243
Регистрация: 16.04.2009
Сообщений: 4,527
19.02.2012, 18:36 9
Цитата Сообщение от silent_1991 Посмотреть сообщение
Как так? Должен оператор присваивания вызываться.
http://liveworkspace.org/code/... 4a50534123
0
Эксперт С++
5042 / 3103 / 271
Регистрация: 11.11.2009
Сообщений: 7,047
19.02.2012, 18:37 10
go, не понял, это опровержение или подтверждение?
1
54 / 54 / 9
Регистрация: 24.09.2011
Сообщений: 149
19.02.2012, 18:40  [ТС] 11
silent_1991, Спасибо за подробное объяснение!!!

Не по теме:

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

0
Эксперт С++
5042 / 3103 / 271
Регистрация: 11.11.2009
Сообщений: 7,047
19.02.2012, 18:44 12
Merovingian, да, в С++ очень много подобных тонкостей. И, что странно, меньше их со временем не становится...
0
go
Эксперт С++
3643 / 1375 / 243
Регистрация: 16.04.2009
Сообщений: 4,527
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/... 7f946f606f
Что Вы здесь имели ввиду?

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

Добавлено через 30 секунд
Цитата Сообщение от Merovingian Посмотреть сообщение
TString& operator=(const TString);
Этого не заметил
0
Эксперт С++
5042 / 3103 / 271
Регистрация: 11.11.2009
Сообщений: 7,047
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 Посмотреть сообщение
Этого не заметил
Не поэтому вызывается конструктор с параметром.
0
go
Эксперт С++
3643 / 1375 / 243
Регистрация: 16.04.2009
Сообщений: 4,527
19.02.2012, 18:50 15
Как бы я не про то спрашивал. Вы правы.
Цитата Сообщение от silent_1991 Посмотреть сообщение
Не поэтому вызывается конструктор с параметромю
В смысле? Сравните.
http://liveworkspace.org/code/... 9f0d7f6996
http://liveworkspace.org/code/... 7f946f606f
0
Эксперт С++
5042 / 3103 / 271
Регистрация: 11.11.2009
Сообщений: 7,047
19.02.2012, 18:53 16
go, конструктор вызывается не потому, что объект передаётся по значению (мне показалось, ты именно об этом говорил), а потому, что нет оператора присваивания, принимающего const char *.
0
go
19.02.2012, 18:54     Объясните про инициализацию
  #17

Не по теме:

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

2
19.02.2012, 18:54
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
19.02.2012, 18:54
Привет! Вот еще темы с ответами:

Объясните про наследование
class A { protected: int n; // закрыты для A, но доступны для B public: virtual void...

Популярно объясните про указатели
Что-то плохо даётся мне тема про указатели. Я хорошо уяснил, что вот так создаётся указатель: ...

Вопрос про инициализацию
Всем привет. Народ подскажите, хочу сделать клиент-серверное приложение, как сделать чтобы в TForm...

Скринсейвер, вопросы про первичную инициализацию параметров
Сразу скажу, objective-c я не знаю, но мне очень нужно сделать простенький скринсейвер. Сейчас...


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

Или воспользуйтесь поиском по форуму:
17
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2021, vBulletin Solutions, Inc.