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

С++ для начинающих

Войти
Регистрация
Восстановить пароль
 
Merovingian
54 / 54 / 5
Регистрация: 24.09.2011
Сообщений: 149
#1

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

19.02.2012, 17:56. Просмотров 678. Ответов 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);

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

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

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

Объясните про наследование - C++
class A { protected: int n; // закрыты для A, но доступны для B public: virtual void func(void) = 0; }; class B: public...

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

Объясните задачу про представление вещественных чисел в памяти компьютера - C++
Собственно знать как и что представляется в компе - необходимо, а особенно как представляются вещественные числа. Как я рассуждаю: ...

Включение, как правильно сделать инициализацию - C++
Вот код: #ifndef WINE_H_ #define WINE_H_ #include &lt;iostream&gt; #include &lt;string&gt; #include &lt;valarray&gt; template&lt;typename T1,...

Добавить инициализацию и удаление в приведенный код - C++
Есть программа: #include &lt;iostream.h&gt; main() { cout &lt;&lt; &quot;Всем привет\n&quot;; } Как ее изменить, чтобы она выдавала: Инициализация ...

После регистрации реклама в сообщениях будет скрыта и будут доступны все возможности форума.
OstapBender
583 / 521 / 35
Регистрация: 22.03.2011
Сообщений: 1,585
19.02.2012, 18:02     Объясните про инициализацию #2
Merovingian, сделай TString& operator=(const char*);
и будет тебе 1 вызов
silent_1991
Эксперт С++
4958 / 3034 / 149
Регистрация: 11.11.2009
Сообщений: 7,027
Завершенные тесты: 1
19.02.2012, 18:20     Объясните про инициализацию #3
Цитата Сообщение от Merovingian Посмотреть сообщение
s = s1 - вызывается TString(const TString& s)
Как так? О_о Должен оператор присваивания вызываться.
go
Эксперт C++
3586 / 1366 / 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
Эксперт С++
4958 / 3034 / 149
Регистрация: 11.11.2009
Сообщений: 7,027
Завершенные тесты: 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
Эксперт С++
4958 / 3034 / 149
Регистрация: 11.11.2009
Сообщений: 7,027
Завершенные тесты: 1
19.02.2012, 18:34     Объясните про инициализацию #8
Цитата Сообщение от Merovingian Посмотреть сообщение
Сам в шоке! Действительно так
"Не верю!" (с)

Цитата Сообщение от Merovingian Посмотреть сообщение
Этого будет достаточно?
Я бы ещё позволил одиночный символ присваивать.
go
Эксперт C++
3586 / 1366 / 128
Регистрация: 16.04.2009
Сообщений: 4,528
19.02.2012, 18:36     Объясните про инициализацию #9
Цитата Сообщение от silent_1991 Посмотреть сообщение
Как так? Должен оператор присваивания вызываться.
http://liveworkspace.org/code/5e1854...c1484a50534123
silent_1991
Эксперт С++
4958 / 3034 / 149
Регистрация: 11.11.2009
Сообщений: 7,027
Завершенные тесты: 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
Эксперт С++
4958 / 3034 / 149
Регистрация: 11.11.2009
Сообщений: 7,027
Завершенные тесты: 1
19.02.2012, 18:44     Объясните про инициализацию #12
Merovingian, да, в С++ очень много подобных тонкостей. И, что странно, меньше их со временем не становится...
go
Эксперт C++
3586 / 1366 / 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
Эксперт С++
4958 / 3034 / 149
Регистрация: 11.11.2009
Сообщений: 7,027
Завершенные тесты: 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++
3586 / 1366 / 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
Эксперт С++
4958 / 3034 / 149
Регистрация: 11.11.2009
Сообщений: 7,027
Завершенные тесты: 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++
Доброго дня. Объясните пожалуйста почему это код хорошо работает: #include &lt;iostream&gt; using namespace std; int main() { ...

Объясните - C++
Вот собственно и программа... #include &lt;stdlib.h&gt; #include &lt;stdio.h&gt; #include &lt;math.h&gt; using namespace std; int...

объясните - C++
Использую Dev-C++, после компиляции, при выполнении программы надпись не на русском языке, а не понятно что. Почему? Текст программы: ...

объясните - C++
ребят вот программа с помощью кой как получилась но не фига в ней понять не могу если можно примеры кодов жтой проги попроще или объясните...


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

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

Не по теме:

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

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

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