С Новым годом! Форум программистов, компьютерный форум, киберфорум
С++ для начинающих
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 4.50/30: Рейтинг темы: голосов - 30, средняя оценка - 4.50
8 / 8 / 2
Регистрация: 14.01.2013
Сообщений: 141

Что такое forward декларация функции?

11.03.2013, 00:48. Показов 6150. Ответов 17
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
Вот в этом примере узнал об этом :
C++
1
2
3
4
5
6
7
8
9
10
11
struct S { 
    static int i; 
    S()        { ++i; } 
    S(const S&) { ++i; } 
};
int S::i = 0;
 
int main() { 
    S v(S()); 
    return S::i; 
}
Могли бы вы поподробней объяснить что это и где применяется?
0
Лучшие ответы (1)
Programming
Эксперт
39485 / 9562 / 3019
Регистрация: 12.04.2006
Сообщений: 41,671
Блог
11.03.2013, 00:48
Ответы с готовыми решениями:

Что такое Forward Voltage @ 1A в эмуляторе
Здравствуйте. Что означает параметр "Forward Voltage @ 1A" в параметрах разных диодов? Какие есть нормальные единицы которые заменяет это...

Неявная декларация функции «gets»
Доброе время суток! Столкнулся с такой проблемой. Мне нужно считывать текстовые данные из консоли и обрабатывать их далее. Следующий код не...

Декларация чистоты функции в сигнатуре
На вике haskell-у польстили: указали что в нём есть Декларации чистоты функций. Я задумался. Прям таки указания в сигнатуре чего то вроде...

17
Каратель
Эксперт С++
6610 / 4029 / 401
Регистрация: 26.03.2010
Сообщений: 9,273
Записей в блоге: 1
11.03.2013, 01:25
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
struct foo; //struct forward declaration
 
foo spam();       //function forward declaration
void eggs(foo);  //function forward declaration
 
struct bar 
{
    foo* mPtr;
    foo& mRef;
};
 
struct foo
{
};
 
int main()
{
   foo obj_foo = spam();
   bar obj_bar = { &obj_foo, obj_foo };
   eggs(*obj_bar.mPtr);
   eggs(obj_bar.mRef);
   
}
 
foo spam() //function definition
{ 
    return foo(); 
} 
 
void eggs(foo) //function definition
{
}
2
 Аватар для OstapBender
594 / 532 / 76
Регистрация: 22.03.2011
Сообщений: 1,585
11.03.2013, 01:34
Jupiter, разжаловали?
0
11.03.2013, 01:42

Не по теме:

OstapBender, нет времени, да и скучно

0
 Аватар для OstapBender
594 / 532 / 76
Регистрация: 22.03.2011
Сообщений: 1,585
11.03.2013, 02:05
Jupiter, понимаю
0
8 / 8 / 2
Регистрация: 14.01.2013
Сообщений: 141
11.03.2013, 02:20  [ТС]
Jupiter, То есть прототип, объявление и forward декларация - это одно и тоже в случае с классами, структурами и функциями или же чем то различаются?
А это
C++
1
S v(S());
только для локальной видимости. Но почему компилятор воспринял как функцию, а не как создание объекта, ведь есть же конструктор, который сможет принять этот аргумент?
И чем объясняется такое условие в стандарте, что предпочтении отдается функцие? Можно пример навести когда была бы спорная ситуация и по этому решили отдавать предпочтении для функции?
0
Каратель
Эксперт С++
6610 / 4029 / 401
Регистрация: 26.03.2010
Сообщений: 9,273
Записей в блоге: 1
11.03.2013, 02:46
Цитата Сообщение от mzarb Посмотреть сообщение
То есть прототип, объявление и forward декларация - это одно и тоже в случае с классами, структурами и функциями или же чем то различаются?
имея прототип функции - можно её вызывать и брать адрес
имея предварительную декларацию класса/структуры - можно использовать ссылки/указатели на эту структуру/класс или создавать другие прототипы

Цитата Сообщение от mzarb Посмотреть сообщение
Но почему компилятор воспринял как функцию, а не как создание объекта, ведь есть же конструктор, который сможет принять этот аргумент?
И чем объясняется такое условие в стандарте, что предпочтении отдается функцие?
тем что все что похоже на декларацию функции является декларацией функции
и такой код тоже валидный
C++
1
2
3
4
5
6
7
8
9
10
11
#include <iostream>
 
void foo(int(i))
{
   std::cout << i;
}
 
int main()
{
   foo(5);
}
1
8 / 8 / 2
Регистрация: 14.01.2013
Сообщений: 141
11.03.2013, 22:35  [ТС]
Jupiter, А ещё насчет этого S v(S()); если здесь добавить скобки чтобы было так S v((S())); то объект создается и это потому что S() воспринимается как выражение, то есть так же как например S v(2+2), что вызвало бы инициализацию объекта с использованием конструктора S(int) { ++i; }; ?
А эти три объявления эквивалентны : S v; S v((S())); S v = S(); ?

Не по теме:

Можно ли здесь на форуме в сообщениях писать код так, чтобы не было отдельного блока с Код Code, а чтобы просто подсветило синтаксис, но не переносило строку?

0
Каратель
Эксперт С++
6610 / 4029 / 401
Регистрация: 26.03.2010
Сообщений: 9,273
Записей в блоге: 1
11.03.2013, 23:14
Цитата Сообщение от mzarb Посмотреть сообщение
А эти три объявления эквивалентны : S v; S v((S())); S v = S(); ?
нет, в первом объявлении вызывается конструктор по умолчанию, во оставшихся двух - конструктор копирования
Цитата Сообщение от mzarb Посмотреть сообщение
А ещё насчет этого S v(S()); если здесь добавить скобки чтобы было так S v((S())); то объект создается и это потому что S() воспринимается как выражение, то есть так же как например S v(2+2), что вызвало бы инициализацию объекта с использованием конструктора S(int) { ++i; }; ?
да
0
8 / 8 / 2
Регистрация: 14.01.2013
Сообщений: 141
11.03.2013, 23:51  [ТС]
Цитата Сообщение от Jupiter Посмотреть сообщение
нет, в первом объявлении вызывается конструктор по умолчанию, во оставшихся двух - конструктор копирования
Но в этом коде :
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
#include <iostream>
using namespace std;
class S {
public:
    static int i;
    S()         {cout << "constructor" << endl; ++i; }
    S(const S&) {cout << "constructor copy" << endl; ++i; }
};
 
int S::i = 0;
 
int main() {
   S v1;
   S v2((S()));
   S v3 = S();
    cout << S::i;
    system("pause");
    return 0;
}
в этих трех случаях выводится только сообщение "constructor", а "constructor copy" нет, хотя если сделать конструктор копий приватным членом, то последние два варианта не будут работать. Почему же тогда не выводится сообщение "constructor copy" ?
0
~ Эврика! ~
 Аватар для OhMyGodSoLong
1258 / 1007 / 74
Регистрация: 24.07.2012
Сообщений: 2,002
12.03.2013, 00:17
Потому что return value optimization. Если её отключить, то будет ожидаемое
Code
1
2
3
4
5
6
constructor
constructor
constructor copy
constructor
constructor copy
5
1
Каратель
Эксперт С++
6610 / 4029 / 401
Регистрация: 26.03.2010
Сообщений: 9,273
Записей в блоге: 1
12.03.2013, 00:22
Цитата Сообщение от mzarb Посмотреть сообщение
Почему же тогда не выводится сообщение "constructor copy" ?
см. сообщение OhMyGodSoLong

1
8 / 8 / 2
Регистрация: 14.01.2013
Сообщений: 141
12.03.2013, 15:05  [ТС]
Jupiter, А можно как-то вызвать функцию func с помощью указателя на нее, который не имеет имени?
Вот код :
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
#include <iostream>
using namespace std;
class S {  
public:
   int i;
   S()         {cout << "constructor" << endl; ++i; }
   S(const S&) {cout << "constructor copy" << endl; ++i; }
 
};
 
ostream& operator<<(ostream & stream,const S &obj){
   stream << obj.i;
   return stream;
}
 
int main() {
   S v(S(*p)());
   S func();  
   cout << v(&func) << endl;
   return 0;
}
 
S func(){
   cout << "in func" << endl;
   S dd;
   return dd;
}
S v(S(*p)()){
   S v=S();
   (*p)();
   v.i = 4;
   return v;
}
То есть вызвать функцию func в этом коде можно по её псевдониму (*p)(); , но как её вызвать если бы у этого псевдонима не было имени, то есть не S v(S(*p)()); , а S v(S()); ?
И почему нельзя вернуть поток не по ссылке, то есть не так ostream& operator<<(ostream & stream,const S &obj), а так ostream operator<<(ostream & stream,const S &obj) ?
0
Каратель
Эксперт С++
6610 / 4029 / 401
Регистрация: 26.03.2010
Сообщений: 9,273
Записей в блоге: 1
12.03.2013, 18:32
Лучший ответ Сообщение было отмечено как решение

Решение

Цитата Сообщение от mzarb Посмотреть сообщение
То есть вызвать функцию func в этом коде можно по её псевдониму (*p)(); , но как её вызвать если бы у этого псевдонима не было имени, то есть не S v(S(*p)()); , а S v(S()); ?
никак, это всё равно что:
C++
1
2
3
void foo(int)
{
}
хоть что переддавай внутрь этой функции но к её параметру не доступишся

Цитата Сообщение от mzarb Посмотреть сообщение
И почему нельзя вернуть поток не по ссылке, то есть не так ostream& operator<<(ostream & stream,const S &obj), а так ostream operator<<(ostream & stream,const S &obj) ?
у потоков нет конструктора копирования, потому передавать и возвращать по значению нельзя
3
 Аватар для Игорь с++
500 / 474 / 63
Регистрация: 26.01.2011
Сообщений: 2,033
12.03.2013, 19:29
Цитата Сообщение от Jupiter Посмотреть сообщение
и такой код тоже валидный
Я прошу прощение , а валидным вы его назвали из за того , что не объявлен портатип функции и сразу описывается функция ?
0
Каратель
Эксперт С++
6610 / 4029 / 401
Регистрация: 26.03.2010
Сообщений: 9,273
Записей в блоге: 1
12.03.2013, 20:27
Цитата Сообщение от Игорь с++ Посмотреть сообщение
Я прошу прощение , а валидным вы его назвали из за того , что не объявлен портатип функции и сразу описывается функция ?
нет, из-за того что параметр взят в скобки
1
 Аватар для Игорь с++
500 / 474 / 63
Регистрация: 26.01.2011
Сообщений: 2,033
12.03.2013, 23:55
Цитата Сообщение от Jupiter Посмотреть сообщение
нет, из-за того что параметр взят в скобки
спасибо , не обратил внимание
0
8 / 8 / 2
Регистрация: 14.01.2013
Сообщений: 141
13.03.2013, 02:17  [ТС]
Цитата Сообщение от Jupiter Посмотреть сообщение
нет, из-за того что параметр взят в скобки
Эти же скобки не несут никакой смысловой нагрузки в данном случае? То есть они только для уточнения спорных моментов, к примеру таких как : "int *(*i)[]", то есть "i" - это указатель на массив из указателей на тип int, а если бы не было скобок, то было бы "i" - это массив из указателей на указатели на тип int.
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
inter-admin
Эксперт
29715 / 6470 / 2152
Регистрация: 06.03.2009
Сообщений: 28,500
Блог
13.03.2013, 02:17
Помогаю со студенческими работами здесь

Декларация прототипа функции с параметром typedef struct
Добрый вечер, господа. Создана typedef struct с несколькими полями. Создаю новую void функцию, которой должен передать структуру с...

Что такое Функции в C++
Можете объяснить что такое функции в C++, только подробно. Я не понимаю как они работают и да объясните что такое функции прототипы!...

Что такое файловый буфер? Что такое режим (модификатор) доступа, при работе с файлами?
Что такое файловый буфер? Что такое режим (модификатор) доступа, при работе с файлами?

Что такое IIS и что такое PWS? Почему одно без другого не работает?
вот уже второй день пытаюсь немного разобраться в АСП. накидал небольшую тестовую страничку. но с серверами я ничего не понимаю! что...

Избиваться от предупреждения: "неявная декларация функции «strlen»?
Добрый день!Подскажите, пожалуйста, как избиваться от предупреждения:&quot;неявная декларация функции «strlen»? Программа написана в среде...


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

Или воспользуйтесь поиском по форуму:
18
Ответ Создать тему
Новые блоги и статьи
WordPad для Windows 11
Jel 10.01.2026
WordPad для Windows 11 — это приложение, которое восстанавливает классический текстовый редактор WordPad в операционной системе Windows 11. После того как Microsoft исключила WordPad из. . .
Classic Notepad for Windows 11
Jel 10.01.2026
Old Classic Notepad for Windows 11 Приложение для Windows 11, позволяющее пользователям вернуть классическую версию текстового редактора «Блокнот» из Windows 10. Программа предоставляет более. . .
Почему дизайн решает?
Neotwalker 09.01.2026
В современном мире, где конкуренция за внимание потребителя достигла пика, дизайн становится мощным инструментом для успеха бренда. Это не просто красивый внешний вид продукта или сайта — это. . .
Модель микоризы: классовый агентный подход 3
anaschu 06.01.2026
aa0a7f55b50dd51c5ec569d2d10c54f6/ O1rJuneU_ls https:/ / vkvideo. ru/ video-115721503_456239114
Owen Logic: О недопустимости использования связки «аналоговый ПИД» + RegKZR
ФедосеевПавел 06.01.2026
Owen Logic: О недопустимости использования связки «аналоговый ПИД» + RegKZR ВВЕДЕНИЕ Введу сокращения: аналоговый ПИД — ПИД регулятор с управляющим выходом в виде числа в диапазоне от 0% до. . .
Модель микоризы: классовый агентный подход 2
anaschu 06.01.2026
репозиторий https:/ / github. com/ shumilovas/ fungi ветка по-частям. коммит Create переделка под биомассу. txt вход sc, но sm считается внутри мицелия. кстати, обьем тоже должен там считаться. . . .
Расчёт токов в цепи постоянного тока
igorrr37 05.01.2026
/ * Дана цепь постоянного тока с сопротивлениями и напряжениями. Надо найти токи в ветвях. Программа составляет систему уравнений по 1 и 2 законам Кирхгофа и решает её. Последовательность действий:. . .
Новый CodeBlocs. Версия 25.03
palva 04.01.2026
Оказывается, недавно вышла новая версия CodeBlocks за номером 25. 03. Когда-то давно я возился с только что вышедшей тогда версией 20. 03. С тех пор я давно снёс всё с компьютера и забыл. Теперь. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru