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

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

Войти
Регистрация
Восстановить пароль
 
 
Рейтинг: Рейтинг темы: голосов - 12, средняя оценка - 4.75
mzarb
-211 / 7 / 1
Регистрация: 14.01.2013
Сообщений: 141
#1

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

11.03.2013, 00:48. Просмотров 1842. Ответов 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)
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
11.03.2013, 00:48
Здравствуйте! Я подобрал для вас темы с ответами на вопрос Что такое forward декларация функции? (C++):

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

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

Что такое рекурсивный тип данных? Что такое конструкция рекурсивного типа? - C++
Что такое рекурсивный тип данных? Что такое конструкция рекурсивного типа?

Что такое виртуальные функции? - C++
Всем привет! Ребята, что такое виртуальная функция? Как пользоваться ими и для чего они нужны? Может кто объяснить?

Что такое обертка функции? - C++
дана функция на входе получает 2 параметра имя и возраст. srting children(string ima, int age) Нужно написать обертку, для...

Что такое ссылки на функции? - C++
Хай. Вопрос в заголовке. Можно, пожалуйста с примером. Спасибо.

Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
Jupiter
Каратель
Эксперт С++
6554 / 3975 / 226
Регистрация: 26.03.2010
Сообщений: 9,273
Записей в блоге: 1
Завершенные тесты: 2
11.03.2013, 01:25 #2
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
583 / 521 / 35
Регистрация: 22.03.2011
Сообщений: 1,585
11.03.2013, 01:34 #3
Jupiter, разжаловали?
0
Jupiter
11.03.2013, 01:42
  #4

Не по теме:

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

0
OstapBender
583 / 521 / 35
Регистрация: 22.03.2011
Сообщений: 1,585
11.03.2013, 02:05 #5
Jupiter, понимаю
0
mzarb
-211 / 7 / 1
Регистрация: 14.01.2013
Сообщений: 141
11.03.2013, 02:20  [ТС] #6
Jupiter, То есть прототип, объявление и forward декларация - это одно и тоже в случае с классами, структурами и функциями или же чем то различаются?
А это
C++
1
S v(S());
только для локальной видимости. Но почему компилятор воспринял как функцию, а не как создание объекта, ведь есть же конструктор, который сможет принять этот аргумент?
И чем объясняется такое условие в стандарте, что предпочтении отдается функцие? Можно пример навести когда была бы спорная ситуация и по этому решили отдавать предпочтении для функции?
0
Jupiter
Каратель
Эксперт С++
6554 / 3975 / 226
Регистрация: 26.03.2010
Сообщений: 9,273
Записей в блоге: 1
Завершенные тесты: 2
11.03.2013, 02:46 #7
Цитата Сообщение от 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
mzarb
-211 / 7 / 1
Регистрация: 14.01.2013
Сообщений: 141
11.03.2013, 22:35  [ТС] #8
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
Jupiter
Каратель
Эксперт С++
6554 / 3975 / 226
Регистрация: 26.03.2010
Сообщений: 9,273
Записей в блоге: 1
Завершенные тесты: 2
11.03.2013, 23:14 #9
Цитата Сообщение от 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
mzarb
-211 / 7 / 1
Регистрация: 14.01.2013
Сообщений: 141
11.03.2013, 23:51  [ТС] #10
Цитата Сообщение от 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
~ Эврика! ~
1243 / 992 / 42
Регистрация: 24.07.2012
Сообщений: 2,002
12.03.2013, 00:17 #11
Потому что return value optimization. Если её отключить, то будет ожидаемое
Код
constructor
constructor
constructor copy
constructor
constructor copy
5
1
Jupiter
Каратель
Эксперт С++
6554 / 3975 / 226
Регистрация: 26.03.2010
Сообщений: 9,273
Записей в блоге: 1
Завершенные тесты: 2
12.03.2013, 00:22 #12
Цитата Сообщение от mzarb Посмотреть сообщение
Почему же тогда не выводится сообщение "constructor copy" ?
см. сообщение OhMyGodSoLong

http://*******/wOlNz
1
mzarb
-211 / 7 / 1
Регистрация: 14.01.2013
Сообщений: 141
12.03.2013, 15:05  [ТС] #13
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
Jupiter
Каратель
Эксперт С++
6554 / 3975 / 226
Регистрация: 26.03.2010
Сообщений: 9,273
Записей в блоге: 1
Завершенные тесты: 2
12.03.2013, 18:32 #14
Лучший ответ Сообщение было отмечено автором темы, экспертом или модератором как ответ
Цитата Сообщение от 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
Игорь с++
436 / 459 / 16
Регистрация: 26.01.2011
Сообщений: 2,032
12.03.2013, 19:29 #15
Цитата Сообщение от Jupiter Посмотреть сообщение
и такой код тоже валидный
Я прошу прощение , а валидным вы его назвали из за того , что не объявлен портатип функции и сразу описывается функция ?
0
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
12.03.2013, 19:29
Привет! Вот еще темы с ответами:

Что такое прототип функции? - C++
Зачем нужен прототип функции ведь она и без него прекрасно работает? Если можете объясните как чайнику в подробностях) заранее спасибо...

Что такое функции и с чем их едят? - C++
Составить подпрограмму сортировки элементов столбца. С возможностью выбора сортировки. Используя подпрограмму рассортировать элементы...

Что означает такое обьявление функции? - C++
SimpleCat &amp;TheFunction()

Что такое хэндлер файла? Что такое файловый указатель? - C++
Что такое хэндлер файла? Что такое файловый указатель?


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

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

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