8 / 9 / 1
Регистрация: 30.06.2011
Сообщений: 250
|
|||||||||||
1 | |||||||||||
объяснить функцию09.10.2011, 17:44. Показов 2254. Ответов 26
Метки нет (Все метки)
Всем привет!
Есть код:
Объектов 3, помогите понять что твориться в этих строках
0
|
09.10.2011, 17:44 | |
Ответы с готовыми решениями:
26
Объяснить функцию Объяснить функцию проверки степени Объяснить функцию perevod Объяснить функцию арксинус |
448 / 211 / 21
Регистрация: 07.10.2011
Сообщений: 462
|
||||||
09.10.2011, 17:52 | 2 | |||||
Не понятно, какое отношение имеет код к заданию о количестве объектов, ну ладно
1) почему строка
А так это объявление дружественной функции инкремента для класса и реализация этой функции.
1
|
8 / 9 / 1
Регистрация: 30.06.2011
Сообщений: 250
|
|
09.10.2011, 18:13 [ТС] | 3 |
дело в том, что препод дал только код из книги и все
Добавлено через 15 минут Извините, но можно поподробнее объяснить что и зачем? Заранее благодарен
0
|
5828 / 3479 / 358
Регистрация: 08.02.2010
Сообщений: 7,448
|
|
09.10.2011, 18:20 | 4 |
плохая книга
вынеси определение функции INC из класса. Прочитай где-нибудь про дружественные функции. Все вопросы отпадут сами собой
1
|
Заблокирован
|
|
09.10.2011, 18:23 | 5 |
- объявление класса integer1 с конструктором преобразования
и privat(закрытой переменной) - объявление дружественной функции INC (она инкрементирует(увеличивает) privat-переменную класса integer1) В программе это - объявление 3-х перемменных класса integer1(в данном случае класс integer1 выступает как созданный нами отдельный тип данных) - переинициализируем переменную у типа integer1 через конструктор преобразования (после данного конструктора значение privat-переменной станет равным 5) вызов дружественной классу integer1 функции в качестве параметра которой вызван конструктор преобразования INC(x), в результате в private переменных z и х будет 6
1
|
Заблокирован
|
|
09.10.2011, 18:32 | 6 |
Тут вам, как всегда, "грамотные" модераторы дали неверные советы.
Дружественная функция может быть определена внутри класса. Что касается вашего вопроса про выделенные вами строки, то это задается дружественная функция INC вашего класса integer1. То есть сначала она объявляется, а затем следом внутри класса определяется. В этом случае эта функция является встраиваемой. Друзьями класса (в том числе дружественной функцией) является функция или класс, которые не являются членами класса, для которого они определены дружественными, но при этом они могут использовать закрытые и защищенные имена членов данного класса. То есть в вашем классе член val объявлен со спецификатором доступа private, то есть это означает , что вне класса к нему обратиться нельзя. Тем не менее класс таким правом обращения к своему закрытому члену val наделяет функцию INC. Эта функция будет иметь доступ к этому закрытому члену класса и сможет его изменять.
1
|
Заблокирован
|
|
09.10.2011, 18:34 | 7 |
Mr. Pyatachok, я тут немножко вам солгал, простите пожалусто!
- это вызов дружественной функции в результате у.val переинициализируем x.val = (5++) = 6 - это тот же вызов френд функции, причём сразу 2-жды z.val = ((6++)++) = 8!
1
|
448 / 211 / 21
Регистрация: 07.10.2011
Сообщений: 462
|
||||||
09.10.2011, 18:41 | 8 | |||||
Разве здесь вызывается конструктор преобразования? здесь у присваивается результат работы функции. Работать должен конструктор копий, созданный компилятором по умолчанию, или операция присваивания, опять же созданная компилятором по умолчанию. Поправьте, если ошибаюсь
Результаты работы программы в VS2010 x y z 5 0 0 5 6 0 5 6 7 Мне VS2010 на попытку написания тела дружественной функции в теле класса после прототипа выдала ошибку линковки. хотя если неписать прототип, а сделать сразу
1
|
Заблокирован
|
|||||||||||||||||||||
09.10.2011, 18:45 | 9 | ||||||||||||||||||||
Кстати сказать, в С++ функция main должна иметь тип возвращаемого значения int, а не void, как у вас написано. То есть должно быть объявление
Кроме того заголовок iostream следует писать без расширения .h, то есть в виде
Любой конструктор с одним параметром или с несколькими параметрами, когда остальные параметры кроме первого имеют аргументы по умолчанию, в том числе и конструктор копирования, называются определенными пользователем функциями преобразования. Что касается ошибки линковки, то у Майкрософт VC++ здесь имеется баг. Более того этот баг присутствует и в VC++ 2010. В VC 2010 вообще куча багов! Пример самого простого мною найденного бага
Данный совершенно корректный код на VC 2010 не компилируется! Правда это относится к компилятору без SP1. С SP1 я не проверял, исправили они ошибку или нет.
1
|
448 / 211 / 21
Регистрация: 07.10.2011
Сообщений: 462
|
|
09.10.2011, 18:49 | 10 |
Но тут-то как раз не было определено конструктора копий, а значит, мы не можем назвать его определенными пользователем функциями преобразования. Для меня здесь один конструктор, объявленный пользователем, он же конструктор преобразования из int в integer1. И он там не вызвался. Возможно, плохо владею терминологией
А так можно? я не знала
1
|
5828 / 3479 / 358
Регистрация: 08.02.2010
Сообщений: 7,448
|
||||||
09.10.2011, 18:52 | 11 | |||||
а в чем тогда тут проблема?
Код
-*- mode: compilation; default-directory: "/home/nameless/samples/cpp/" -*- Compilation started at Mon Oct 10 01:48:30 make -j8 g++ -c -Wall -g -std=c++0x main.cc g++ -o sample main.o main.o: In function `main': /home/nameless/samples/cpp/main.cc:16: undefined reference to `INC(integer1)' /home/nameless/samples/cpp/main.cc:17: undefined reference to `INC(integer1)' /home/nameless/samples/cpp/main.cc:17: undefined reference to `INC(integer1)' collect2: выполнение ld завершилось с кодом возврата 1 make: *** [sample] Ошибка 1 Compilation exited abnormally with code 2 at Mon Oct 10 01:48:31 Код
[nameless@desktop ~]$ gcc --version gcc (GCC) 4.6.1 20110908 (Red Hat 4.6.1-9)
1
|
448 / 211 / 21
Регистрация: 07.10.2011
Сообщений: 462
|
|
09.10.2011, 18:53 | 12 |
Nameless One, подозреваю, что если в теле класса поместить определение дружественной функции без прототипа, то должно все работать. а вот если и прототип. и потом реализация - то нет
1
|
Заблокирован
|
|
09.10.2011, 18:58 | 13 |
Это не имеет значения, сами мы определили конструктор копирования, или он для нас создан компилятором по умолчанию. Важно, что имеется один параметр.
Что касается примера со структурой, то это совершенно корректный код, если в определении структуры не объявлен конструктор. Дело в том, что в языке С, с которым С++ желательно должен быть максимально совместим, имя структуры и имена переменных, ее членов, находятся в разных пространствах имен. Если считать предложенную конструкцию некорректной, то тогда огромное число кода, написанного на С, будет не компилироваться на С++.
1
|
8 / 9 / 1
Регистрация: 30.06.2011
Сообщений: 250
|
||||||
09.10.2011, 19:04 [ТС] | 14 | |||||
Извините за наглость, но можете еще прокомментировать еще один код и я отстану со своими нубскими вопрсами
0
|
Заблокирован
|
|
09.10.2011, 19:07 | 15 |
Вполне возможно, что у обоих компиляторов имеется данный баг. Здесь проблема связана с тем, что в классе одновременно присутствует объявление и определение дружественной функции. Скорей всего компилятор gcc разделяет эти две функции. То есть проблема заключается в том, что функция, впервые объявленная в виде дружественной в классе, имеет внешнее связывание. Тогда как функции, являющиеся встраиваемыми, имеют внутреннее связывание. Когда одно и тоже имя определено как имеющее внешнее связывание и внутреннее связывание, то поведение не определенное.
Попробуйте убрать из класса объявление функцуии и оставьте только определение и прокомпилируйте с помощью gcc. Мне самому будет интересен результат. Чтобы сомнений не было, я процитирую стандарт, раздел 11.4 "Friends" #5. "A function can be defined in a friend declaration of a class if and only if the class is a non-local class"
1
|
5828 / 3479 / 358
Регистрация: 08.02.2010
Сообщений: 7,448
|
|
09.10.2011, 19:10 | 16 |
Mr. Pyatachok, там не на что смотреть, кроме как на реализацию оператора доступа по индексу. Он возвращает символ пробела, если переданный индекс больше либо равен размеру хранимой строки, и соответствующий символ строки. И да, в 20 строке мы выйдем за границы массива. Ну или если передадим отрицательный индекс.
1
|
Заблокирован
|
|
09.10.2011, 19:11 | 17 |
Здесь у вас ничего работать не будет, так как нет определений конструкторов класса. А так у вас определен класс, который имеет три конструктора, включая конструктор копирования, и оператор [], который возвращает символ строки по заданному индексу, либо символ пробела, если индекс превосходит или равен длине строки.
1
|
5828 / 3479 / 358
Регистрация: 08.02.2010
Сообщений: 7,448
|
|
09.10.2011, 19:14 | 18 |
с friend integer1 INC(integer1 scr) {scr.val++; return scr;} все нормально компилируется. Видимо, это и имеется в виду под "definition in a friend declaration". Просто выглядит довольно сомнительным, что у двух самых популярных компиляторов имеется один и тот же баг
Mr. Pyatachok, где ты такой код берешь?
1
|
8 / 9 / 1
Регистрация: 30.06.2011
Сообщений: 250
|
|
09.10.2011, 19:17 [ТС] | 19 |
Извините но книгу препод не показал.
0
|
Заблокирован
|
|
09.10.2011, 19:19 | 20 |
Правильно ли я понял, что вы проверили использование определения этой дружественной функции внутри класса, убрав из класса предварительное ее объявление, и у вас с помощью gcc все скомпилировалось? Если это так, то объяснение, как я уже указал, кроется в том, что gcc рассматривал эти два объявления (предварительное объявление и определение), как две различные функции, так как они имеют разное связывание: внешнее и внутреннее.
Что касается Майкрософт VC++ 2010, то, даже убрав из класса предварительное объявление, код не компилируется. То есть имеет место очевидный баг. Например, на старом Borland Builder 5.0 этот код компилируется.
0
|
09.10.2011, 19:19 | |
09.10.2011, 19:19 | |
Помогаю со студенческими работами здесь
20
Объяснить функцию двухмерного массива Объяснить пожалуйста мне эту функцию Объяснить $(this) Объяснить Искать еще темы с ответами Или воспользуйтесь поиском по форуму: |