Неопределенная ссылка на 'оператор delete (void *)' - PullRequest
13 голосов
/ 10 августа 2011

Я новичок в программировании на 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.cpp, но не более того.Мне нужно иметь возможность удалить StringWriter из указателя на PacketWriter, и я получаю различные другие подобные ошибки, если я определяю деструктор для StringWriter, виртуальный или нет.Я уверен, что это простая проблема, которую я пропускаю как новичок.

Кроме того, я пишу это для микросхемы AVR, используя avr-g ++ в Windows.

Спасибо

Ответы [ 4 ]

24 голосов
/ 26 марта 2015

Извините за публикацию в старой теме, но она все еще довольно высока в результатах поиска Google, и если у вас возникла эта проблема, вам действительно следует проверить эту ссылку , потому что там написано, что вам просто нужно ссылка -lstdc ++, и это то, что решило проблему для меня.

Сообщество добавило следующую строку, не выделив ее как таковую, а вместо того, чтобы просто добавить комментарий к моему ответу по причинам, которые мне не нравятся: «Или используйте компилятор C ++, который неявно добавит параметр -lstdc ++, например, g ++.»

14 голосов
/ 10 августа 2011

Если по какой-то причине вы не связываетесь со стандартной библиотекой (что вполне может иметь место во встроенном сценарии), вы должны предоставить свои собственные операторы 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);
}

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

9 голосов
/ 10 августа 2011

Я просто процитирую документацию, так как они написаны лучше.

Написание C ++

Вы можете писать программы для платформы AVR на C ++,если вы включили c ++ во включенные языки во время настройки avr-gcc.Практически все, что описано в разделе «Программы написание C AVR», сначала прочтите это.

Основные недостатки использования C ++:

C++ calling convention side-effects
No libstdc++ support.

C ++побочные эффекты соглашения о вызовах

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

void myfunction(MyCppClass object);

Вы получите сгенерированный конструктор копирования по умолчанию, который вызывается для создания временной копии используемого объекта.в моей функции ().Будьте осторожны, если это не то, что вам нужно: эквивалентное поведение должно быть достижимо путем передачи ссылки на постоянный объект MyCppClass, избегая при этом кода и накладных расходов при выполнении.

Отсутствует libstdc ++ и другие функции C ++

Ни один из стандартных шаблонов, классов или функций C ++ недоступен.Кроме того, операторы new и delete еще не реализованы.

Поддержка исключений C ++ также отсутствует.Возможно, вам понадобится использовать параметр компилятора -fno-exceptions, чтобы отключить исключения в интерфейсе C ++.

Что работает?Несмотря на то, что многие вкусности C ++, с которыми вы привыкли работать, недоступны, может оказаться целесообразным запрограммировать AVR на C ++.Конструкторы и деструкторы являются функциональными, и только организационные преимущества использования классов и объектно-ориентированного программирования могут сделать C ++ отличным выбором.

4 голосов
/ 17 ноября 2012

Если вы просто хотите сделать интерфейс, вам не нужно новый / удалить.Просто удалите «virtual» из деструктора базового класса и убедитесь, что у производного класса есть реализация __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();
};  

В 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

...