Неопределенная ссылка на " оператор delete (void*)"
Я новичок в программировании на C++, но уже давно работаю на C и Java. Я пытаюсь сделать интерфейсную иерархию в каком-то последовательном протоколе, над которым я работаю, и продолжаю получать ошибку:
Undefined reference to 'operator delete(void*)'
(упрощенно) код ниже:
PacketWriter.h:
class PacketWriter {
public:
virtual ~PacketWriter() {}
virtual uint8_t nextByte() = 0;
}
StringWriter.h:
class StringWriter : public PacketWriter {
public:
StringWriter(const char* message);
virtual uint8_t nextByte();
}
конструктор и функции nextByte реализованы в StringWriter.СРР, но ничего больше. Мне нужно иметь возможность удалить a StringWriter от указателя к PacketWriter, и я получаю различные другие подобные ошибки, если я определяю деструктор для StringWriter, виртуальный или нет. Я уверен, что это простая проблема, которую я пропускаю как Новичок.
кроме того, я пишу это для чипа AVR, используя avr-g++ в Windows.
спасибо
4 ответов
если вы по какой-то причине не связываетесь со стандартной библиотекой (как это может быть во встроенном сценарии), вы должны предоставить свои собственные операторы new
и delete
. В простейшем случае, вы можете просто обернуть malloc
, или выделить память из вашего собственного любимого источника:
void * operator new(std::size_t n)
{
void * const p = std::malloc(n);
// handle p == 0
return p;
}
void operator delete(void * p) // or delete(void *, std::size_t)
{
std::free(p);
}
вам никогда не придется делать это, если вы компилируете для обычной, размещенной платформы, поэтому, если вам нужно это сделать, вам лучше быть знакомым с тонкостями памяти управление на вашей платформе.
извините за публикацию в старой теме, но она по-прежнему довольно высока в результатах поиска Google, и если у вас есть эта проблема, вы действительно должны проверить этой ссылке, потому что там говорится, что вам просто нужно связать-lstdc++ и это то, что решило проблему для меня.
следующая строка была добавлена сообществом, не выделяя ее как таковую и вместо того, чтобы просто добавить комментарий к моему ответу по причинам, которые ускользают от меня: "Или использовать компилятор C++, который будет неявно добавьте параметр-lstdc++, например g++."
Я просто процитирую документацию, так как они положить его лучше.
Написание C++
вы можете писать программы для платформы AVR на C++, если вы включили c++ в enabled-языках во время настройки avr-gcc. Просто обо всем в разделе написание программ C AVR применяется, поэтому читал, что первый.
основными недостатками использования C++ являются:
C++ calling convention side-effects No libstdc++ support.
C++ вызов побочных эффектов конвенции
некоторые функции C++ автоматически генерируют подразумеваемый код, если требуется, который может тратить ценное пространство памяти программы и процессор время. Например, если в какой-то момент в программе функция передал объект C++ по значению:
void myfunction(MyCppClass object);
вы получите конструктор копирования по умолчанию и вызывается для создания временной копии объекта, используемого в myfunction (). Быть осторожны, если это не что вы хотите: эквивалентное поведение должно быть достижимый путем передачи ссылки на постоянный объект MyCppClass, при этом избегая кода и выполнения накладных расходов.
отсутствует libstdc++ и другие функции C++
ни один из стандартных шаблонов, классов или функций C++ не доступный. Кроме того, операторам new и delete еще предстоит выполненный.
поддержка исключений C++ также отсутствует. Вы, вероятно, должны сделать обязательно используйте параметр компилятора-fno-exceptions, чтобы отключить исключения в интерфейсе C++.
работает? Несмотря на то, что многие лакомства C++ вы привыкли чтобы работа с ними была недоступна, может быть стоит запрограммировать AVR на C++. Конструкторы и деструкторы функциональны и просто организационные преимущества использования классов и объектно-ориентированного программирование может сделать C++ отличным выбором.
если вы просто хотите сделать интерфейс, вам не нужны новые/удалять. Просто удалите "виртуальный" из деструктора базового класса и убедитесь, что производный класс имеет реализацию __cxa_pure_virtual().
вот компилируемый пример. (Я удалил возврат, чтобы все было просто, но он отлично работает с ними.)
В PacketWriter.h
class PacketWriter {
public:
virtual void nextByte() = 0;
protected:
~PacketWriter() {}
};
В StringWriter.h
#include "PacketWriter.h"
class StringWriter : public PacketWriter {
public:
StringWriter(const char* message);
void nextByte();
};
In Stringwriter не.cpp
#include "StringWriter.h"
// Definition of the error function to call if the constructor goes bonkers
extern "C" void __cxa_pure_virtual() { while (1); }
StringWriter::StringWriter(const char* message)
{
// constructor code here
}
void StringWriter::nextByte()
{
}
компилировать с avr-g++ StringWriter.cpp