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

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

Войти
Регистрация
Восстановить пароль
 
 
Рейтинг: Рейтинг темы: голосов - 9, средняя оценка - 4.78
Mr. Pyatachok
8 / 8 / 0
Регистрация: 30.06.2011
Сообщений: 250
#1

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

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

Всем привет!
Есть код:
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
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
09.10.2011, 17:44
Здравствуйте! Я подобрал для вас темы с ответами на вопрос объяснить функцию (C++):

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

Объяснить программу - C++
объясните пожалуйста программу,что делается на каждом этапе.struct sp{ int inf; sp* adr;} sp *fst,*lst,*tmp; tmp=(sp*)malloc(vl); int...

просьба объяснить - C++
#include &lt;cstdlib&gt; #include &lt;iostream&gt; #include &lt;fstream&gt; using namespace std; int main() { long a, b; char s, c; int i; ...

Объяснить код - C++
Может кто-нибудь смог бы закомментировать данные участок кода или объяснить что за что отвечает( можно еще и ссылки на сторонние ресуры...

Объяснить программу - C++
Объясните пожалуйста каждую строку. #include &lt;iostream&gt; #include &lt;string&gt; #include &lt;algorithm&gt; struct is_punct { ...

Функция (объяснить) - C++
Здраствуйте помогите пожалуйста разобраться в функции Не пойму, мы передаём в функцию символ и массив символов, i- счётчик, по...

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

А так это объявление дружественной функции инкремента для класса и реализация этой функции.
1
Mr. Pyatachok
8 / 8 / 0
Регистрация: 30.06.2011
Сообщений: 250
09.10.2011, 18:13  [ТС] #3
дело в том, что препод дал только код из книги и все

Добавлено через 15 минут
Извините, но можно поподробнее объяснить что и зачем?
Заранее благодарен
0
Nameless One
Эксперт С++
5774 / 3424 / 255
Регистрация: 08.02.2010
Сообщений: 7,447
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
aeshes
440 / 203 / 13
Регистрация: 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
aeshes
440 / 203 / 13
Регистрация: 07.10.2011
Сообщений: 462
09.10.2011, 18:49 #10
Цитата Сообщение от Сыроежка Посмотреть сообщение
Любой конструктор в том числе и конструктор копирования, называются определенными пользователем функциями преобразования.
Но тут-то как раз не было определено конструктора копий, а значит, мы не можем назвать его определенными пользователем функциями преобразования. Для меня здесь один конструктор, объявленный пользователем, он же конструктор преобразования из int в integer1. И он там не вызвался. Возможно, плохо владею терминологией

Цитата Сообщение от Сыроежка Посмотреть сообщение
struct A
{
int A;
};
А так можно? я не знала
1
Nameless One
Эксперт С++
5774 / 3424 / 255
Регистрация: 08.02.2010
Сообщений: 7,447
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
aeshes
440 / 203 / 13
Регистрация: 07.10.2011
Сообщений: 462
09.10.2011, 18:53 #12
Nameless One, подозреваю, что если в теле класса поместить определение дружественной функции без прототипа, то должно все работать. а вот если и прототип. и потом реализация - то нет
1
Сыроежка
Заблокирован
09.10.2011, 18:58 #13
Цитата Сообщение от aeshes Посмотреть сообщение
Но тут-то как раз не было определено конструктора копий, а значит, мы не можем назвать его определенными пользователем функциями преобразования. Для меня здесь один конструктор, объявленный пользователем, он же конструктор преобразования из int в integer1. И он там не вызвался. Возможно, плохо владею терминологией



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

Что касается примера со структурой, то это совершенно корректный код, если в определении структуры не объявлен конструктор. Дело в том, что в языке С, с которым С++ желательно должен быть максимально совместим, имя структуры и имена переменных, ее членов, находятся в разных пространствах имен. Если считать предложенную конструкцию некорректной, то тогда огромное число кода, написанного на С, будет не компилироваться на С++.
1
Mr. Pyatachok
8 / 8 / 0
Регистрация: 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
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
09.10.2011, 19:07
Привет! Вот еще темы с ответами:

Объяснить задание - C++
как понять: &quot;The program should be capable of accepting a multi-line input&quot;

Объяснить строку - C++
while (strchr(S,*str)==strrchr(S,*str) ) объясните строку

Объяснить код - C++
Двоичный поиск #include &quot;stdafx.h&quot; #include &quot;iostream&quot; #include &quot;conio.h&quot; #include &quot;stdio.h&quot; using namespace std; int...

Объяснить выражение - C++
Привет всем. Помогите пожалуйста, объясните, что значит следующее выражение: int value = flex != 0 ? flex : 10000;


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

Или воспользуйтесь поиском по форуму:
15
Yandex
Объявления
09.10.2011, 19:07
Ответ Создать тему
Опции темы

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