Форум программистов, компьютерный форум, киберфорум
С++ для начинающих
Войти
Регистрация
Восстановить пароль
Карта форума Темы раздела Блоги Сообщество Поиск Заказать работу  
 
 
Рейтинг 4.82/11: Рейтинг темы: голосов - 11, средняя оценка - 4.82
8 / 9 / 1
Регистрация: 30.06.2011
Сообщений: 250
1

объяснить функцию

09.10.2011, 17:44. Показов 2254. Ответов 26
Метки нет (Все метки)

Author24 — интернет-сервис помощи студентам
Всем привет!
Есть код:
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
#include<conio.h>
#include<iostream.h>
 
class integer1
{
  int val;
    public:
  integer1(int v0 ) {val=v0;}
  friend integer1 INC(integer1);
  integer1 INC(integer1 scr) {scr.val++; return scr;}
 
};
 
void main()
{
 integer1 x(5),y=(0),z=(0);
 y=INC(x);
 z=INC(INC(x));
 
 getch();
}
Необходимо подсчитать количество объектов и изобразить схему их взаимодействия (копирование, отображение).

Объектов 3, помогите понять что твориться в этих строках
C++
1
2
friend integer1 INC(integer1);
integer1 INC(integer1 scr) {scr.val++; return scr;}
Заранее спасибо
0
Programming
Эксперт
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
09.10.2011, 17:44
Ответы с готовыми решениями:

Объяснить функцию
Добрый вечер всем. Хотел бы разузнать поподробнее что делает эта функция. Заранее прошу объясните...

Объяснить функцию проверки степени
int proverkastepeni(int n) { return !(n&amp;(n-1)); } Нашел вот такую функцию проверки степени, не...

Объяснить функцию perevod
Определить функцию преобразования десятичного числа n в СС( двоичную, восьмеричную,...

Объяснить функцию арксинус
Пришла на ум одна задачка , кто может помочь разобраться в тригонометрии ? Условия и вопрос на...

26
448 / 211 / 21
Регистрация: 07.10.2011
Сообщений: 462
09.10.2011, 17:52 2
Не понятно, какое отношение имеет код к заданию о количестве объектов, ну ладно
1) почему строка
C++
1
integer1 INC(integer1 scr) {scr.val++; return scr;}
находится в пределах класса? Она должна быть за пределами класса

А так это объявление дружественной функции инкремента для класса и реализация этой функции.
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
Цитата Сообщение от Mr. Pyatachok Посмотреть сообщение
дело в том, что препод дал только код из книги и все
плохая книга

Цитата Сообщение от Mr. Pyatachok Посмотреть сообщение
Извините, но можно поподробнее объяснить что и зачем?
вынеси определение функции INC из класса. Прочитай где-нибудь про дружественные функции. Все вопросы отпадут сами собой
1
Заблокирован
Автор FAQ
09.10.2011, 18:23 5
Цитата Сообщение от Mr. Pyatachok Посмотреть сообщение
class integer1
{
* int val;
* * public:
* integer1(int v0 ) {val=v0;}
* friend integer1 INC(integer1);
* integer1 INC(integer1 scr) {scr.val++; return scr;}
};
- объявление класса integer1 с конструктором преобразования
Цитата Сообщение от Mr. Pyatachok Посмотреть сообщение
integer1(int v0 ) {val=v0;}
и privat(закрытой переменной)
Цитата Сообщение от Mr. Pyatachok Посмотреть сообщение
int val;
Цитата Сообщение от Mr. Pyatachok Посмотреть сообщение
friend integer1 INC(integer1);
- объявление дружественной функции INC (она инкрементирует(увеличивает) privat-переменную класса integer1)

В программе это
Цитата Сообщение от Mr. Pyatachok Посмотреть сообщение
integer1 x(5),y=(0),z=(0);
- объявление 3-х перемменных класса integer1(в данном случае класс integer1 выступает как созданный нами отдельный тип данных)

Цитата Сообщение от Mr. Pyatachok Посмотреть сообщение
y=INC(x);
- переинициализируем переменную у типа integer1 через конструктор преобразования (после данного конструктора значение privat-переменной станет равным 5)

Цитата Сообщение от Mr. Pyatachok Посмотреть сообщение
z=INC(INC(x));
вызов дружественной классу integer1 функции
в качестве параметра которой вызван конструктор преобразования INC(x), в результате в private переменных z и х будет 6
1
Заблокирован
09.10.2011, 18:32 6
Тут вам, как всегда, "грамотные" модераторы дали неверные советы.

Дружественная функция может быть определена внутри класса.

Что касается вашего вопроса про выделенные вами строки, то это задается дружественная функция INC вашего класса integer1. То есть сначала она объявляется, а затем следом внутри класса определяется. В этом случае эта функция является встраиваемой.

Друзьями класса (в том числе дружественной функцией) является функция или класс, которые не являются членами класса, для которого они определены дружественными, но при этом они могут использовать закрытые и защищенные имена членов данного класса.

То есть в вашем классе член val объявлен со спецификатором доступа private, то есть это означает , что вне класса к нему обратиться нельзя. Тем не менее класс таким правом обращения к своему закрытому члену val наделяет функцию INC. Эта функция будет иметь доступ к этому закрытому члену класса и сможет его изменять.
1
Заблокирован
Автор FAQ
09.10.2011, 18:34 7
Mr. Pyatachok, я тут немножко вам солгал, простите пожалусто!
Цитата Сообщение от Mr. Pyatachok Посмотреть сообщение
y=INC(x);
- это вызов дружественной функции
Цитата Сообщение от Mr. Pyatachok Посмотреть сообщение
friend integer1 INC(integer1);
в результате у.val переинициализируем x.val = (5++) = 6


Цитата Сообщение от Mr. Pyatachok Посмотреть сообщение
z=INC(INC(x));
- это тот же вызов френд функции, причём сразу 2-жды z.val = ((6++)++) = 8!
1
448 / 211 / 21
Регистрация: 07.10.2011
Сообщений: 462
09.10.2011, 18:41 8
Цитата Сообщение от -=ЮрА=- Посмотреть сообщение
y=INC(x);
- переинициализируем переменную у типа integer1 через конструктор преобразования (после данного конструктора значение privat-переменной станет равным 5)
Разве здесь вызывается конструктор преобразования? здесь у присваивается результат работы функции. Работать должен конструктор копий, созданный компилятором по умолчанию, или операция присваивания, опять же созданная компилятором по умолчанию. Поправьте, если ошибаюсь

Результаты работы программы в VS2010
x y z
5 0 0
5 6 0
5 6 7

Мне VS2010 на попытку написания тела дружественной функции в теле класса после прототипа выдала ошибку линковки. хотя если неписать прототип, а сделать сразу
C++
1
  friend integer1 INC(integer1 scr) {scr.val++; return scr;}
то все работает
1
Заблокирован
09.10.2011, 18:45 9
Кстати сказать, в С++ функция main должна иметь тип возвращаемого значения int, а не void, как у вас написано. То есть должно быть объявление

C++
1
int main()
В крайнем случае, если вам лень писать int, вы можете написать просто

C++
1
main()
так как в С++ действует правило умолчания, для возвращаемых значений функций (по крайней мере в Стандарте С++ 2003 года), то есть если вы не указываете тип возвращаемого значения, то предполагается, что он имеет тип int

Кроме того заголовок iostream следует писать без расширения .h, то есть в виде

C++
1
#include   <iostream>
Добавлено через 3 минуты
Цитата Сообщение от aeshes Посмотреть сообщение
Разве здесь вызывается конструктор преобразования? здесь у присваивается результат работы функции. Работать должен конструктор копий, созданный компилятором по умолчанию, или операция присваивания, опять же созданная компилятором по умолчанию. Поправьте, если ошибаюсь

Результаты работы программы в VS2010
x y z
5 0 0
5 6 0
5 6 7

Мне VS2010 на попытку написания тела дружественной функции в теле класса выдала ошибку линковки. Может, тут конечно имеет место быть несоответствие компилятора стандартам, но все же...
Любой конструктор с одним параметром или с несколькими параметрами, когда остальные параметры кроме первого имеют аргументы по умолчанию, в том числе и конструктор копирования, называются определенными пользователем функциями преобразования.

Что касается ошибки линковки, то у Майкрософт VC++ здесь имеется баг. Более того этот баг присутствует и в VC++ 2010. В VC 2010 вообще куча багов! Пример самого простого мною найденного бага

C++
1
2
3
4
struct A
{
  int A;
};

Данный совершенно корректный код на VC 2010 не компилируется! Правда это относится к компилятору без SP1. С SP1 я не проверял, исправили они ошибку или нет.
1
448 / 211 / 21
Регистрация: 07.10.2011
Сообщений: 462
09.10.2011, 18:49 10
Цитата Сообщение от Сыроежка Посмотреть сообщение
Любой конструктор в том числе и конструктор копирования, называются определенными пользователем функциями преобразования.
Но тут-то как раз не было определено конструктора копий, а значит, мы не можем назвать его определенными пользователем функциями преобразования. Для меня здесь один конструктор, объявленный пользователем, он же конструктор преобразования из int в integer1. И он там не вызвался. Возможно, плохо владею терминологией

Цитата Сообщение от Сыроежка Посмотреть сообщение
struct A
{
int A;
};
А так можно? я не знала
1
Эксперт С++
5828 / 3479 / 358
Регистрация: 08.02.2010
Сообщений: 7,448
09.10.2011, 18:52 11
Цитата Сообщение от Сыроежка Посмотреть сообщение
Дружественная функция может быть определена внутри класса.
а в чем тогда тут проблема?
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
#include<iostream>
 
class integer1
{
  int val;
    public:
  integer1(int v0 ) {val=v0;}
  friend integer1 INC(integer1);
  integer1 INC(integer1 scr) {scr.val++; return scr;}
 
};
 
int main()
{
 integer1 x(5),y=(0),z=(0);
 y=INC(x);
 z=INC(INC(x));
}
Код
-*- 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
Цитата Сообщение от Сыроежка Посмотреть сообщение
Что касается ошибки линковки, то у Майкрософт VC++ здесь имеется баг.
и у gcc тоже баг, да?
Код
[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
Цитата Сообщение от aeshes Посмотреть сообщение
Но тут-то как раз не было определено конструктора копий, а значит, мы не можем назвать его определенными пользователем функциями преобразования. Для меня здесь один конструктор, объявленный пользователем, он же конструктор преобразования из int в integer1. И он там не вызвался. Возможно, плохо владею терминологией



А так можно? я не знала
Это не имеет значения, сами мы определили конструктор копирования, или он для нас создан компилятором по умолчанию. Важно, что имеется один параметр.

Что касается примера со структурой, то это совершенно корректный код, если в определении структуры не объявлен конструктор. Дело в том, что в языке С, с которым С++ желательно должен быть максимально совместим, имя структуры и имена переменных, ее членов, находятся в разных пространствах имен. Если считать предложенную конструкцию некорректной, то тогда огромное число кода, написанного на С, будет не компилироваться на С++.
1
8 / 9 / 1
Регистрация: 30.06.2011
Сообщений: 250
09.10.2011, 19:04  [ТС] 14
Извините за наглость, но можете еще прокомментировать еще один код и я отстану со своими нубскими вопрсами
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
#include<iostream>
#include<conio.h>
#include<stdio.h>
class string1
{
  char *s;
    public:
  string1(char *);
  string1(string1 &);
  string1();
  char operator[](int n)
  { if(n>=strlen(s))return(' ');return(s[n]); }
};
 
void main()
{
  char c,t;
  string1 x("abcd");
  c=x[2];
  t=x[20];
 
 getch();
}
Объясните что и как работает пожалуйста, а то я в ступоре
0
Заблокирован
09.10.2011, 19:07 15
Цитата Сообщение от Nameless One Посмотреть сообщение
а в чем тогда тут проблема?
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
#include<iostream>
 
class integer1
{
  int val;
    public:
  integer1(int v0 ) {val=v0;}
  friend integer1 INC(integer1);
  integer1 INC(integer1 scr) {scr.val++; return scr;}
 
};
 
int main()
{
 integer1 x(5),y=(0),z=(0);
 y=INC(x);
 z=INC(INC(x));
}
Код
-*- 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
и у gcc тоже баг, да?
Код
[nameless@desktop ~]$ gcc --version
gcc (GCC) 4.6.1 20110908 (Red Hat 4.6.1-9)
Вполне возможно, что у обоих компиляторов имеется данный баг. Здесь проблема связана с тем, что в классе одновременно присутствует объявление и определение дружественной функции. Скорей всего компилятор 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
Цитата Сообщение от Mr. Pyatachok Посмотреть сообщение
Извините за наглость, но можете еще прокомментировать еще один код и я отстану со своими нубскими вопрсами
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
#include<iostream>
#include<conio.h>
#include<stdio.h>
class string1
{
  char *s;
    public:
  string1(char *);
  string1(string1 &);
  string1();
  char operator[](int n)
  { if(n>=strlen(s))return(' ');return(s[n]); }
};
 
void main()
{
  char c,t;
  string1 x("abcd");
  c=x[2];
  t=x[20];
 
 getch();
}
Объясните что и как работает пожалуйста, а то я в ступоре
Здесь у вас ничего работать не будет, так как нет определений конструкторов класса. А так у вас определен класс, который имеет три конструктора, включая конструктор копирования, и оператор [], который возвращает символ строки по заданному индексу, либо символ пробела, если индекс превосходит или равен длине строки.
1
Эксперт С++
5828 / 3479 / 358
Регистрация: 08.02.2010
Сообщений: 7,448
09.10.2011, 19:14 18
Цитата Сообщение от Сыроежка Посмотреть сообщение
Попробуйте убрать из класса объявление функцуии и оставьте только определение и прокомпилируйте с помощью gcc. Мне самому будет интересен результат.
с 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
Цитата Сообщение от Nameless One Посмотреть сообщение
с friend integer1 INC(integer1 scr) {scr.val++; return scr;} все нормально компилируется. Видимо, это и имеется в виду под "definition in a friend declaration". Просто выглядит довольно сомнительным, что у двух самых популярных компиляторов имеется один и тот же баг

Mr. Pyatachok, где ты такой код берешь?
Правильно ли я понял, что вы проверили использование определения этой дружественной функции внутри класса, убрав из класса предварительное ее объявление, и у вас с помощью gcc все скомпилировалось? Если это так, то объяснение, как я уже указал, кроется в том, что gcc рассматривал эти два объявления (предварительное объявление и определение), как две различные функции, так как они имеют разное связывание: внешнее и внутреннее.

Что касается Майкрософт VC++ 2010, то, даже убрав из класса предварительное объявление, код не компилируется. То есть имеет место очевидный баг. Например, на старом Borland Builder 5.0 этот код компилируется.
0
09.10.2011, 19:19
IT_Exp
Эксперт
87844 / 49110 / 22898
Регистрация: 17.06.2006
Сообщений: 92,604
09.10.2011, 19:19
Помогаю со студенческими работами здесь

Объяснить функцию двухмерного массива
for n in range(1,5): for k in range(n,5): A = A + 1 A = A + 1 //Остального кода...

Объяснить пожалуйста мне эту функцию
На просторах интернета нашел один из методов адаптивного меню и все по CSS ясно и понятно, но вот в...

Объяснить $(this)
Есть скрипт с Stack Overflow &lt;script&gt; $(document).on(&quot;submit&quot;, &quot;#login-form&quot;,...

Объяснить
Напишите,пожалуйста построчный коментарий,к каждой строке что она делает,и что за функция,и зачем...


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

Или воспользуйтесь поиском по форуму:
20
Ответ Создать тему
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2024, CyberForum.ru