Вопрос по с++, Помогите понять суть |
Здравствуйте, гость ( Вход | Регистрация )
Вопрос по с++, Помогите понять суть |
igor_bogomolov |
13.7.2010, 23:34
Сообщение
#1
|
Профессионал Группа: Сомодератор Сообщений: 1215 Регистрация: 22.3.2009 Из: Саратов Пользователь №: 630 Спасибо сказали: 235 раз(а) Репутация: 29 |
Вопрос из теста.
Раскрывающийся текст
Вопрос в тесте такой - сколько раз вызовется конструктор класса A при исполнении функции main. После ответа откомпилируй код для проверки, добавив какой-нибудь std::cout в конструктор A. При первом просмотре (да и при втором, третьем, ...) я предположил, что конструктор вызовится 4 раза. Откомпилировав, получил всего два вызова. Пробовал воспользоваться отладчиком и впал в недоумение. r1 и r2 вообще не создаются, т.е. при компиляции эти строчки игнорируются. Сделал m_name публичным и попробовал обратиться к нему после создания r1. Получил ошибку компиляции Цитата ошибка: запрос элемента ‘m_name’ в ‘r1’, имеющего не классовый тип ‘A(std::string)’ При этом r3 и r4 создаются нормально и обращение к m_name не приводит к ошибке.Помогите разобраться что происходит |
|
|
DEADHUNT |
14.7.2010, 1:45
Сообщение
#2
|
Активный участник Группа: Участник Сообщений: 430 Регистрация: 15.4.2009 Пользователь №: 686 Спасибо сказали: 26 раз(а) Репутация: 2 |
Это связано с неоднозначностью, компилятор не может отличить декларацию прототипа функции от объявления переменной.
A r1(std::string(v[1])); может рассматриваться как функция A r1(std::string) с параметром по умолчанию v[1] и т. д. |
|
|
Litkevich Yuriy |
14.7.2010, 7:19
Сообщение
#3
|
разработчик РЭА Группа: Сомодератор Сообщений: 9669 Регистрация: 9.1.2008 Из: Тюмень Пользователь №: 64 Спасибо сказали: 807 раз(а) Репутация: 94 |
|
|
|
DIMEDROLL |
14.7.2010, 7:29
Сообщение
#4
|
Участник Группа: Участник Сообщений: 165 Регистрация: 28.9.2008 Из: Киев Пользователь №: 304 Спасибо сказали: 23 раз(а) Репутация: 0 |
вижуал студия сразу выдает предупреждение:
Цитата 1>\testprocload.cpp(32) : warning C4930: 'A r1(std::string [])': prototyped function not called (was a variable definition intended?) 1>\testprocload.cpp(35) : warning C4930: 'A r2(std::string)': prototyped function not called (was a variable definition intended?) Цитата в С++ нельзя функцию объявить внутри другой (например, в main). Что значит нельзя?
отлично компилится Сообщение отредактировал DIMEDROLL - 14.7.2010, 7:33 |
|
|
Алексей1153 |
14.7.2010, 7:55
Сообщение
#5
|
фрилансер Группа: Участник Сообщений: 2941 Регистрация: 19.6.2010 Из: Обливион Пользователь №: 1822 Спасибо сказали: 215 раз(а) Репутация: 34 |
должен 4 раза вызваться - все 4 раза конструктор копирования (поскольку он явно определён)
строчки A r1(std::string(v[1])); и A r3(s); проигнорированы оптимизатором, так как эти локальные переменные нигде далее не использованы. Можно вывести их значение в поток тоже, чтобы они "остались", либо отрубить оптимизацию (а в дебаге должно само остаться, кстати) Это связано с неоднозначностью, компилятор не может отличить декларацию прототипа функции от объявления переменной. Ну ну С каких в C++ стало можно объявлять локальные функции ? [offtop] A r1(std::string(v[1])); может рассматриваться как функция A r1(std::string) с параметром по умолчанию v[1] и т. д. а если бы это и было прототипом, то синтаксис неверен - какой ещё тут параметр по умолчанию ? std::string() - это конструктор класса std::string. А параметр по умолчанию пишется после "=" [/offtop] Что значит нельзя? ты объявил не функцию, сделал предопределение глобальной функции foo ИМХО
Хотя, студия, к примеру, не позволила бы сделать это внутри функции )) Сообщение отредактировал Алексей1153 - 14.7.2010, 7:56 |
|
|
igor_bogomolov |
14.7.2010, 12:36
Сообщение
#6
|
Профессионал Группа: Сомодератор Сообщений: 1215 Регистрация: 22.3.2009 Из: Саратов Пользователь №: 630 Спасибо сказали: 235 раз(а) Репутация: 29 |
должен 4 раза вызваться - все 4 раза конструктор копирования (поскольку он явно определён) Где вы увидели конструктор копирования? Он явно не определён.строчки Вы не внимательно прочитали мое первое сообщение. r2 и r4 тоже нигде далее по коду не используются. Тем не менее они не с оптимизированны, как вы это объясните? С r3 вообще икаких проблем нет. Игнорируются r1 и r2.A r1(std::string(v[1])); и A r3(s); проигнорированы оптимизатором, так как эти локальные переменные нигде далее не использованы Цитата(DEADHUNT) Это связано с неоднозначностью, компилятор не может отличить декларацию прототипа функции от объявления переменной. Цитата(DIMEDROLL) 1>\testprocload.cpp(32) : warning C4930: 'A r1(std::string [])': prototyped function not called (was a variable definition intended?) 1>\testprocload.cpp(35) : warning C4930: 'A r2(std::string)': prototyped function not called (was a variable definition intended?) Спасибо, теперь понятно. |
|
|
DEADHUNT |
14.7.2010, 13:09
Сообщение
#7
|
Активный участник Группа: Участник Сообщений: 430 Регистрация: 15.4.2009 Пользователь №: 686 Спасибо сказали: 26 раз(а) Репутация: 2 |
в С++ нельзя функцию объявить внутри другой (например, в main). Поэтому здесь всё однозначно. объявлять можно(declare), определять нельзя(define). в стандарте также упоминается о неоднозначностях c с примерами - 6.8 Ambiguity resolution 8.3.6 Default arguments: .... 5. A default argument expression is implicitly converted (Clause 4) to the parameter type. The default argu- ment expression has the same semantic constraints as the initializer expression in a declaration of a variable of the parameter type, using the copy-initialization semantics (8.5). The names in the expression are bound, and the semantic constraints are checked, at the point where the default argument expression appears. Name lookup and checking of semantic constraints for default arguments in function templates and in mem- ber functions of class templates are performed as described in 14.7.1. [ Example: in the following code, g will be called with the value f(2): с этим загнался. Сообщение отредактировал DEADHUNT - 14.7.2010, 13:17 |
|
|
igor_bogomolov |
14.7.2010, 13:14
Сообщение
#8
|
Профессионал Группа: Сомодератор Сообщений: 1215 Регистрация: 22.3.2009 Из: Саратов Пользователь №: 630 Спасибо сказали: 235 раз(а) Репутация: 29 |
Еще подсказали. Достаточно выражение в r1 и r2 заключить еще в одни скобки и неоднозначность пропадет.
|
|
|
Алексей1153 |
14.7.2010, 14:13
Сообщение
#9
|
фрилансер Группа: Участник Сообщений: 2941 Регистрация: 19.6.2010 Из: Обливион Пользователь №: 1822 Спасибо сказали: 215 раз(а) Репутация: 34 |
мдя, ночь без сна сказалась ))
Где вы увидели конструктор копирования? Он явно не определён. Да, это я протупил. Там тип ссылки же не A r2 и r4 тоже нигде далее по коду не используются. Да, теперь вижу Сорри за дезинформацию Сообщение отредактировал Алексей1153 - 14.7.2010, 14:13 |
|
|
ЙаМайскЫйПчОЛ |
14.7.2010, 17:17
Сообщение
#10
|
Участник Группа: Участник Сообщений: 154 Регистрация: 10.7.2008 Из: СПб Пользователь №: 232 Спасибо сказали: 7 раз(а) Репутация: 5 |
Этож... 3.14дец
Так всетаки он это чуствовал как прототип функции??? А то у нас тут работа остановилась. |
|
|
Текстовая версия | Сейчас: 23.11.2024, 7:24 |