Привет. У меня есть класс: Код (C++): class TimeLine { public: bool IsExecuted; DateTime Timestamp; int Command; int Argument; }; Правильно ли создавать его экземпляр следующим образом: Код (C++): TimeLine item; item = new TimeLine(); Во всяком случае, транслятор не ругается. И уже почти 20 лет я это делаю на C#. Однако его использование в дальнейшем, например так Код (C++): timeLines.push(item); вызывает следующее сообщение об ошибке: no match for 'operator=' (operand types are 'TimeLine' and 'TimeLine*') timeLines - ну это некая реализация Queue, не думаю, что в ней проблема. Как это фикснуть? Спасибо.
Если на стеке, то: Код (C++): TimeLine item; Если на куче, то: Код (C++): TimeLine* item = new TimeLine();
Не работает. Код Код (C++): TimeLine* item = new TimeLine(); timeLines.push(item); выдает ошибку no matching function for call to 'QueueList<TimeLine>:ush(TimeLine*&)' Библиотека для работы с очередями взята отсюда http://playground.arduino.cc/Code/QueueList Что это за амперсанд оно требует?
Да, и еще. Метод push в этой библиотеке объявлен так: Код (C++): // push an item to the queue. void push (const T i); Почему там константа? Константы хранятся в стеке. Может ли экземпляр класса быть константой? Если да, то как создать новый экземпляр в куче и объявить его константой? В общем, мне нужен лист экземпляров класса (не обязательно очередь). Лист, к которому можно добавлять новые экземпляры, созданные в куче. Ну и соответственно, удалять из листа. Есть ли какая-нибудь бесплатная реализация? Спасибо.
Начну с "константы". const в данном контексте означает, что параметр не может быть изменен в пределах функции. По поводу ошибки Код (C++): no matching function for call to 'QueueList<TimeLine>::push(TimeLine*&) Ругается, что нет реализации функции, в которую передается указатель на TimeLine. Терзают смутные сомнения, что в функцию push надо передавать не указатель, а переменную типа TimeLine. Т.е надо примерно так: Код (C++): TimeLine item(); timeLines.push(item); Указатель на класс передать вменяемым образом в объявленную подобным образом функцию push не получится.
Хорошо. Если я задам как вы пишете, значит ли это, что в стеке будет зарезевировано слово под адрес на место в куче, где хранится сам экземпляр? (со стеком облом, как в Z80. Ничтожный размер). Я создаю 15-20 экземпляров. Это значит из стека будет забрано в 15-20 слов при таком объявлении? В принципе, ничего. Если я выйду из процедуры, весь ее стек со своими локальными перенными будет рециклирован и адреса остануться только в экземпляре timeLines. Если это так, то ничего. Пожалуйста поправьте, если не так.
Ну,хорошо. Объявил класс как Код (C++): class TimeLine { public: TimeLine(); bool IsExecuted; DateTime Timestamp; int Command; int Argument; }; Вызов Код (C++): TimeLine item(); timeLines.push(item); транслируется с ошибкой no matching function for call to 'QueueList<TimeLine> : : push(TimeLine (&)())' Что может быть не так?
Если там так объявлено - выкиньте в топку этот класс, там T передаётся по значению. Надо, чтобы было объявлено так: Код (C++): void push (const T& i) Подводных косяков с этой "библиотекой" будет - вагон и тележка, это я вам гарантирую.
А если по логике так нужно -- передавать по значению, что бы не менять исходный объект (потому и const применяется). Вы торопитесь с выводами.
По логике в таких случаях всё равно передают по ссылке и ставят модификатор const - компилятор по рукам настучит, если что. Так что это вы торопитесь с выводами . Передавать огромную структуру, например, по значению - это говнокод. Коего на playground.arduino.cc - тонны. Впрочем, никак не настаиваю, каждый ССЗБ. Просто, применяя шаблоны, надо уметь их правильно готовить. Просмотрев код "библиотеки" по ссылке, для себя сделал вывод - говно. З.Ы. И кстати сказать: передавая по значению, const можно выбросить в топку, т.к. всё равно на стеке создаётся копия объекта. И хоть обменяйтесь там внутри него - на исходный объект это никак не повлияет. З.З.Ы. Если что, то передача указателя - это не передача по значению. Також как передача по ссылке.
Я не делал ни каких выводов, поэтому и торопиться не могу. Что касается const компилятор настучит только в пределах тела функции. А если предполагается, что в очереди должны храниться объекты, которые ни кем ни при каких условиях не должны меняться. В этом случае при передаче по ссылке ни какой const Вам не поможет, только передача по значению с копированием объектов и такой же возврат с копированием объектов "спасут отца русской демократии". Правда в условиях ограниченности памяти в AVR вполне вероятно, что нужно применять другие шаблоны проектирования. const указывает что копия объекта не может быть изменена. И по поводу const -- бытует мнение, что 'const' много не бывает, и его нужно применять везде, где только можно. Хотя я это мнение не разделяю полностью. Так что прежде, чем записывать код в категорию "говно", нужно понять для чего он создавался и в каких случаях должен использоваться и только потом делать выводы.
Вот и глянули бы код "библиотеки", и тогда бы поняли, что моё определение - безошибочно. Остальной ваш бред комментировать не буду, просто вывешу эту смешную простыню потомкам: Оставлю себе на память, чтобы веселиться при случае. З.Ы. Надеюсь, вы не хуже меня знаете, сколько говна собрано в поставке стандартных библиотек Arduino IDE - косяк на косяке, кучу warning и т.п. Зачем ещё множить фекал, скачивая его очередную порцию? Учиться надо на хорошем, а не на абы чём.
Попробовал сам. Наблюдается интересный эффект. Если так: Код (C++): TimeLine item(); timeLines.push(item); действительно, компилируется с ошибкой. А если так: Код (C++): TimeLine item; timeLines.push(item); то без ошибки.
Код (C++): TimeLine item(); Это объявление функции, которая возвращает объект типа TimeLine. (Интересно кто Вам так посоветовал объявлять объект класса?) И ошибка: Код (Text): no matching function for call to 'QueueList<TimeLine> : : push(TimeLine (&)())' сообщает о том, что нет реализации функции QueueList<TimeLine>:: push, которая в качестве параметра принимает указатель на функцию, т.к. такой функции действительно нет.
Простая логика. Есть конструктор Код (C++): TimeLine() . Если бы конструктор имел параметры, то объявление экземпляра класса было бы таким Код (C++): TimeLine item(параметры); А для объявления функции логичнее такая конструкция: Код (C++): TimeLine item(void); И еще помнится, с каким-то компилятором С++ (уже не помню, каким) объявлял экземпляр класса с конструктором без параметров именно так: Код (C++): TimeLine item(); , и он "не обижался". А на самом деле конструктор класса без параметров крайне редко приходится применять. Уже и не помню, когда последний раз так делал.
Если не ошибаюсь для 'С' так делать обязательно, а для 'C++' нет. Поэтому возникает неоднозначность, которую разработчики компилятора решили в пользу объявления функции. Тогда уж и экземпляры класса логичней создавать следующим образом: Код (C++): TimeLine item = TimeLine(); -- экземпляр 'item' является результатом работы конструктора 'TimeLine()'. Что собственно и является одним из способов объявления экземпляров класса, а запись вида: Код (C++): TimeLine item; // или TimeLine item(параметры); это его сокращенные формы.