Не допускается указание типа возвращаемого значения для конструктора

Обновлено: 18.05.2024

К сожалению, вы получаете ту же бесполезную ошибку в Visual Studio 2019 (cl.exe v19.26.28806). Подсказка от компилятора MSVC была бы кстати. Видимо gcc компилятор уже это делает. Я обнаружил свою ошибку, только скопировав еще один рабочий класс в файл с ошибкой .h и .cpp . После медленного удаления функций, перестроения, повторения я в конце концов перешел к версии с голыми костями, которая работала. и тогда я заметил недостающую точку с запятой. Аргх!

Вам не хватает точки с запятой после вашего struct определения.

Ошибка правильная, конструкторы не имеют возвращаемого типа. Поскольку у вас отсутствует точка с запятой, все определение структуры рассматривается как тип возвращаемого значения для функции, например:

Добавьте точку с запятой:

Спасибо. Кстати, кто-нибудь знает, что в С++ 0x не будет необходимости в этой глупой точке с запятой? Когда вы думаете об этом, это несколько несовместимо с другими конструкциями в С++. Или я что-то упускаю?

Это своего рода похмелье, объявление структуры — это определение типа, а объявление класса выглядит как структура. ps VS2010 предупреждает вас об этом!

@Martin: это не просто «похмелье» от C. Что-то вроде: class < /* . */ >object; разрешено, поэтому точка с запятой необходима, чтобы сообщить компилятору, что он достиг конца определения класса.

Вам нужен лучший компилятор. С г++:

Точка с запятой необходима, потому что она завершает возможный список экземпляров структуры:

Создает три экземпляра B с именами x, y и z. Это часть наследия C++ C++, и она останется в C++0x.

+1 за ответ, -1 за обоснование. Относительно легко реализовать (для профессионалов), что если после скобки ничего нет, это конец decl.

@atch Теперь вы эксперт по разбору C++? Дело в том , что после структуры есть что-то — ваш конструктор.

@GMan Или даже просто парсер. Очень легко создавать неоднозначные грамматики, которые выглядят правильными, но имеют тонкие проблемы.

@atch: поскольку вы спросили, «сколько людей когда-либо использовали это» (имея в виду декларатор после определения типа, я просмотрел общедоступные заголовочные файлы Windows (фактически windef.h и winbase.h) и не смог найти ни одного экземпляра, который не имел декларатора.Иногда это было typedef (или четыре, для вариантов указателя), иногда это было имя вложенной структуры, но КАЖДОЕ объявление структуры использовало декларатор.

Возникла проблема с кодом, не знаю, как ее решить. Пишет, что нельзя указывать тип возвращаемого значения для конструктора. На всякий случай сообщу, что мне необходимо, чтоб оно мониторило book[1] на поиск слова "Program" и в случае, если найдет, выводило дату и автора (book[2],book[3]).

void founder() <>; замените на void founder(); . Помимо этого у вас ничего в класс не добавляется, в конструкторе вы присваиваете данные локально переменной. которая уничтожается при выходе из конструктора. А еще после класса должна стоять точка с запятой. ;

1 ответ 1

Если ваш код в точности такой, то по сути у вас написано

Т.е. объявлен конструктор, возвращающий этот самый class Book . А конструктор ничего возвращать не должен. Итак, нужна точка с запятой после объявления класса.

После этого компилятор совершенно справедливо поясняет, что book в конструкторе скрывает имя book в классе - т.е. то, что вы написали в конструкторе

не имеет никакого отношения к полю book в классе, которое так и остается не инициализированным.

Теперь выползает очередная ошибка - что ваша void Book::founder() уже имеет текст реализации - и в самом деле, ведь в классе вы ее не просто объявили, а определили, как имеющую пустое тело. А теперь - непустое. Компилятор на ruSO не участвует, понимать, что программист хотел, не умеет. Исправляем и эту ошибку, убирая <> у функции в объявлении класса.

Теперь компилятору не нравится void у main() - и его можно понять: стандарт ведь требует int .

И вот только после этого код компилируется.

Но, скорее всего, не работает (хотя, может, вы хотели именно этого - пишете же, что "мониторить book[1] надо, т.е. искать "Program" среди дат. ). Хотя бы потому, что все элементы массивов нумеруются с 0, так что вы благополучно опускаете первый элемент, а в цикле выходите за пределы массива. И сравниваете, кстати, вторую строку массива book , с датами.

И только переписав цикл как

мы получим какой-то вывод.

Итак, у вас как минимум 4 ошибки. Причем о трех из них, которые мешали компиляции, компилятор сообщал вполне доступным языком.

некоторые говорят, что нет возврата, потому что нет способа вернуться - синтаксис запрещает это - да, это имеет смысл, но я считаю, что все функции должны что-то вернуть, нет? Другие говорят, что конструктор возвращает только что созданный объект, который, кажется, делает sense, так как оператор присваивания используется в конструкторе. У других есть и другие интересные объяснения.

конструкторы не вызываются как другие функции, поэтому они не возвращаются как другие функции. Они выполняются как побочный эффект определенных конструкций (cast, new , определение переменной, ctor-инициализатор-список, pass-by-value, return-by-value).

конструктор не указывает возвращаемый тип, потому что он был бы избыточным: нет другого типа, кроме создаваемого, который конструктор мог бы потенциально "вернуть". Я помещаю "return" в кавычки, потому что технически конструкторы ничего не возвращают: когда они вызываются в статическом контексте, они инициализируют экземпляр на месте; когда они вызываются в динамическом контексте, это оператор new Это возвращает что-то, а не конструктор.

конструктор строит на месте, ему не нужно ничего возвращать.

Я считаю, что все функции должны возвращать что-то

предполагая, что конструкторы могут что-то вернуть, это имеет проблемные последствия для следующего вызова функции:

предотвращение возврата функций конструктора облегчает использование анонимных временных файлов, а также многих других функций C++. Без такого правила безобидные утверждения могут стать двусмысленными:

возможность конструкторов возвращать значение, усложняет создание объектов-имеющих один однозначный тип, имя класса при отсутствии произвольных возвращаемых значений позволяет избежать таких проблем.

но я считаю, что все функции должны что-то возвращать, нет?

нет. Что значит возвращать значение из функции? Ну, ABI для реализации будет указывать, что для некоторого возвращаемого типа функция будет устанавливать определенные регистры или некоторую память с некоторым смещением от указателя стека к значению, которое "возвращается" функцией.

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

Так что нет, функции не должны ничего возвращать.

что конструкторам не хватает возвращаемого типа -- даже void -- означает, что вы не можете вызвать конструктор из кода C++. В этом-то все и дело. Вызов конструктора не имеет смысла. Запрещение вызова конструктора исключает саму возможность ошибки этого типа пользователя.

редактировать

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

вы не можете вызывать конструкторы из кода C++, потому что конструкторы не имеют имени. Создание конструкторов без возвращаемого типа подчеркивает программисту, что конструкторы-это совсем другой вид функции, чем другие функции. То, что конструктор действительно возвращает, если он возвращает что-либо, зависит от поставщика.

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

теперь, если Вы себе это представляете X::initialize во втором примере должны были быть возвращены, сказать bool указывая на успех или неудачу, у вас будет проблема. В main() , невнимательный программист может получить X это неправильно инициализировано, что приводит к неопределенному поведению (обычно трудно отлаживаемый сбой, который может не быть обнаружен до производства).

это одна из основных причин, почему конструкторы сделали специальное. Единственные два способа выхода из конструктора - это обычное завершение или исключение, которое должны затем обрабатывается вызывающим абонентом (или передается вверх по стеку). В любом случае, вы предотвратите попадание в неинициализированные объекты.

в качестве примечания, неинициализированные объекты являются одной из наиболее распространенных причин ошибок в C, которая не имеет ничего, чтобы помочь программисту, как это.

конструкторы неявно возвращают экземпляр самого класса. Это будет противоречить, если он был разработан, чтобы вернуть что-то, и программист вернул что-то совершенно отличное от самого класса. В основном синтаксис будет запутанным.

Некоторые говорят, что возврата нет, потому что нет возможности вернуть - синтаксис запрещает это - да, это имеет смысл, но я считаю, что все функции должны что-то возвращать, нет? Другие говорят, что конструктор как бы возвращает сам вновь созданный объект, что кажется логичным, поскольку в конструкторе используется оператор присваивания. У третьих есть другие интересные объяснения.


Из любопытства, когда было бы полезно или даже иметь смысл, чтобы конструктор возвращал что-либо, кроме объекта, который он создает?

Кто сказал, что конструктор - это функция? (Помимо того факта, что это описано в стандартном разделе «Специальные функции-члены»)

Конструкторы не вызываются, как другие функции, поэтому они не возвращаются, как другие функции. Они выполняются как побочный эффект определенных конструкций (приведение ,, new определение переменной, ctor-initializer-list , передача по значению, возврат по значению).


Конструктор не указывает возвращаемый тип, потому что он был бы избыточным: не существует другого типа, кроме конструируемого, который конструктор потенциально мог бы «вернуть». Я заключил «return» в кавычки, потому что технически конструкторы ничего не возвращают: когда они вызываются в статическом контексте, они инициализируют экземпляр на месте; когда они вызываются в динамическом контексте, то что- new то возвращает оператор , а не конструктор.

Конструктор строит на месте, ему не нужно ничего возвращать.

I believe that all functions have to return something

@DavidHammen Это разница только в синтаксисе. Объявление типа возвращаемого значения функцией void имеет то же значение.

Разница только в синтаксисе? Конструктор - это функция void в том смысле, что оператор return должен быть return; в конструкторе. Однако, делая конструктор не вызываемым и оставляя тип возвращаемого значения неопределенным, стандарт, по-видимому, позволяет поставщику компилятора иметь конструктор, возвращающий что-то, пока он действует так, как будто он возвращает void.

@DavidHammen Тот факт, что конструкторы не вызываются и что они указаны так, чтобы ничего не возвращать, не дает реализациям такой широты. Это делает правило «как если бы». Реализации могут приводить к тому, что вызываемые функции, возвращающие значение, «возвращают» другие вещи, если они ведут себя в соответствии со стандартом.

@DavidHammen: вы уверены, что у них нет возвращаемого типа? На данный момент я понимаю, что у них нет имени и типа возвращаемого значения, такого же, как у класса. Единственная разница в том, что body вернет void, но оценка все равно приведет к заданному типу.

Предполагая, что конструкторы могут что-то возвращать, это имеет проблемные последствия для следующего вызова функции:

Предотвращение возврата функций конструктора облегчает использование анонимных временных библиотек, а также многих других функций C ++. Без такого правила безобидные утверждения могут стать двусмысленными:

Возможность конструкторов возвращать значение усложняет создание объектов - наличие единственного однозначного типа, имени класса, при отсутствии произвольных возвращаемых значений, позволяет избежать таких проблем.

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

but I believe that all functions have to return something, no?

Нет. Что значит вернуть значение из функции? Что ж, ABI для реализации будет указывать, что для некоторого возвращаемого типа функция устанавливает определенные регистры или некоторую память с некоторым смещением от указателя стека на значение, которое «возвращается» функцией.

Очевидно, что регистры и память существуют и содержат данные после вызова конструктора или функции void, но язык говорит, что эти функции ничего не возвращают, и поэтому ABI не указывает, в какие регистры или память следует искать возвращаемое значение. Код не может установить возвращаемое значение, а вызывающий код может получить любое возвращаемое значение.

Так что нет, функции не должны ничего возвращать.

Отсутствие у конструкторов возвращаемого типа - даже нет void - означает, что вы не можете вызвать конструктор из своего кода C ++. И в этом суть. Вызов конструктора не имеет смысла. Недопустимость вызова конструктора исключает саму возможность возникновения пользовательской ошибки этого типа.

Редактировать

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

Вы не можете вызывать конструкторы из кода C ++, потому что у конструкторов нет имени. Отсутствие у конструкторов возвращаемого типа подчеркивает для программиста, что конструкторы - это совершенно другой вид функций, чем другие функции. Что конструктор действительно возвращает, если он что-либо возвращает, зависит от поставщика.


Тот факт, что конструкторы ничего не возвращают, не имеет ничего общего с тем, можете ли вы вызвать конструктор. Вы не можете вызвать конструктор, потому что у конструкторов нет имени и нет синтаксиса для его вызова. (Только обходной путь; размещение новое).

Конструкторы, пожалуй, плохая репутация для этого. Это практически инициализатор для заранее созданных объектов. Самый простой способ проиллюстрировать это - псевдо-пример эквивалентной конструкции без использования конструкторов C ++.

Теперь, если вы вообразите, что X::initialize во втором примере bool нужно было заставить возвращаться, скажем, указывающий на успех или неудачу, у вас возникнет проблема. In main() , невнимательный программист может получить ошибку, X которая не инициализирована должным образом, что приведет к неопределенному поведению (обычно это сложный для отладки сбой, который может не быть обнаружен до производства).

Это одна из основных причин, почему конструкторы делают особенными. Единственные два способа выйти из конструктора: обычное завершение или исключение, которое затем должно быть обработано вызывающим (или передано вверх по стеку). В любом случае вы предотвратите появление неинициализированных объектов.

В качестве примечания, неинициализированные объекты являются одной из наиболее частых причин ошибок в C, который не может помочь программисту.

Кто-то говорит, что возврата нет, потому что возврата нет — синтаксис это запрещает — да, в этом есть смысл, но я считаю, что все функции должны что-то возвращать, нет? Другие говорят, что конструктор как бы возвращает сам только что созданный объект, что кажется логичным, поскольку в конструкторе используется оператор присваивания. Третьи имеют другие интересные объяснения.


Из любопытства, когда было бы полезно или даже целесообразно, чтобы конструктор возвращал что-либо, кроме объекта, который он создает? - kevin628

AFAIK возвращает вновь созданный объект. - Tamer Shlash

Кто сказал, что конструктор — это функция? (Помимо того, что это описано в стандартном разделе "Специальные функции-члены") - Ben Voigt

8 ответы

Конструкторы не вызываются, как другие функции, поэтому они не возвращаются, как другие функции. Они выполняются как побочный эффект определенных конструкций (cast, new , определение переменной, ctor-инициализатор-список, передача по значению, возврат по значению).

ответ дан 27 апр.


Конструктор не указывает возвращаемый тип, потому что это было бы избыточно: нет другого типа, кроме создаваемого, который конструктор потенциально мог бы «вернуть». Я заключил «возврат» в кавычки, потому что технически конструкторы ничего не возвращают: когда они вызываются в статическом контексте, они инициализируют экземпляр на месте; когда они вызываются в динамическом контексте, это оператор new который возвращает что-то, а не конструктор.

ответ дан 27 апр.

и то, что внешность как вызов конструктора на самом деле является приведением. - Бен Фойгт

Конструктор строится на месте, ему не нужно ничего возвращать.

Я считаю, что все функции должны что-то возвращать

ответ дан 27 апр.

Конструкторы даже не возвращаются void (если это имеет смысл). У них нет возвращаемого типа. - Дэвид Хаммен

@DavidHammen Разница только в синтаксисе. Объявление типа возвращаемого значения функции void имеет такое же значение. - беймс53

Разница только в синтаксисе? Конструктор — это пустая функция в том смысле, что оператор return должен быть return; в конструкторе. Однако, сделав конструктор недоступным для вызова и оставив тип возвращаемого значения неуказанным, стандарт, по-видимому, позволяет поставщику компилятора заставить конструктор возвращать что-то, пока он действует так, как если бы он возвращал void. - Дэвид Хаммен

@DavidHammen Тот факт, что конструкторы нельзя вызывать и что они не возвращают ничего, не дает реализациям такой широты. Правило «как если бы» делает это. Реализации могут привести к тому, что вызываемые функции, возвращающие значение, будут «возвращать» другие вещи, пока они ведут себя в соответствии со стандартом. - беймс53

@DavidHammen: вы уверены, что у них нет возвращаемого типа? Мое текущее понимание состоит в том, что у них нет имя и тип возвращаемого значения такой же, как у класса. Единственная разница в том, что body вернет void, и все же оценка приведет к данному типу. - лорро

Предполагая, что конструкторы могут что-то возвращать, это имеет проблематичные последствия для следующего вызова функции:

Предотвращение возврата функций конструктора упрощает использование анонимных временных объектов, а также многих других функций C++. Без такого правила безобидные утверждения могут стать двусмысленными:

Способность конструкторов возвращать значение усложняет создание объектов — наличие единственного однозначного типа, имени класса при отсутствии произвольных возвращаемых значений позволяет избежать подобных проблем.

ответ дан 27 апр.

этот аргумент заставил бы нас поверить, что конструктор, возвращающий произвольные значения, был бы желателен, если бы он не мешал другим установленным языковым функциям неправильно. напротив, конструктор - это функция специального назначения. используется для инициализации объектов своего класса. пересмотрите свой ответ в этом свете. - user1055604

но я считаю, что все функции должны что-то возвращать, не так ли?

Нет. Что значит вернуть значение из функции? Что ж, ABI для реализации будет указывать, что для некоторого возвращаемого типа функция будет устанавливать определенные регистры или часть памяти по некоторому смещению от указателя стека на значение, которое «возвращается» функцией.

Очевидно, что регистры и память существуют и содержат данные после вызова конструктора или функции void, но язык говорит, что эти функции ничего не возвращают, и поэтому ABI не указывает, в каких регистрах или памяти искать возвращаемое значение. Код не может установить возвращаемое значение, а вызывающий код может получить любое возвращаемое значение.

Так что нет, функции не должны ничего возвращать.

ответ дан 27 апр.

В конструкторах отсутствует тип возвращаемого значения — даже void -- означает, что вы не можете вызвать конструктор из кода C++. И в этом суть. Вызов конструктора не имеет смысла. Запрещение вызова конструктора устраняет саму возможность такой ошибки пользователя.

Редактировать

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

Вы не можете вызывать конструкторы из кода C++, потому что у конструкторов нет имени. Если конструкторы не имеют возвращаемого типа, это подчеркивает для программиста, что конструкторы — это функции совершенно другого типа, чем другие функции. Что на самом деле возвращает конструктор, если он что-то возвращает, зависит от поставщика.

ответ дан 27 апр.


Тот факт, что конструкторы ничего не возвращают, не имеет ничего общего с тем, можете ли вы вызвать конструктор. Вы не можете вызвать конструктор, потому что у конструкторов нет имени и синтаксиса для его вызова. (Только обходной путь; размещение новое). - беймс53

Конструкторы, пожалуй, плохое имя для этого. Это практически инициализатор для предварительно созданных объектов. Проще всего проиллюстрировать это на псевдопримере эквивалентной конструкции без использования конструкторов C++.

Теперь, если представить, что X::initialize во втором примере должны были вернуться, скажем, bool указывая на успех или неудачу, у вас возникнут проблемы. В main() , невнимательный программист может получить X который не инициализирован должным образом, что приводит к неопределенному поведению (обычно трудно отлаживаемому сбою, который может быть не обнаружен до начала производства).

Это одна из основных причин, по которой конструкторы делаются особенными. Есть только два способа выйти из конструктора: через обычное завершение или через исключение, которое должен затем обрабатывается вызывающей стороной (или передается вверх по стеку). В любом случае вы предотвращаете появление неинициализированных объектов.

В качестве примечания, неинициализированные объекты являются одной из наиболее распространенных причин ошибок в C, который ничем не может помочь программисту.

Читайте также: