Неопределенная ссылка на " оператор 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