对'operator delete(void *)'的未定义引用

时间:2011-08-10 17:40:40

标签: c++ embedded destructor avr avr-gcc

我是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中实现,但没有别的。我需要能够从指向PacketWriter的指针中删除StringWriter,如果我为StringWriter定义了一个析构函数,我是否已经得到了各种其他类似的错误。我敢肯定这是一个简单的问题,我作为一个新手忽略了。

另外,我正在为AVR芯片编写这个,在Windows上使用avr-g ++。

谢谢

4 个答案:

答案 0 :(得分:24)

很抱歉在旧帖子中发帖,但谷歌的搜索结果仍然很高,如果你有这个问题,你真的应该看看this link,因为它说你只需要链接-lstdc ++就可以解决这个问题。

社区添加了以下行,但没有突出显示它,而是仅仅为了避免我的回答而添加注释: "或者使用将隐式添加-lstdc ++选项的C ++编译器,例如:例++"

答案 1 :(得分:14)

如果由于某种原因没有链接标准库(在嵌入式方案中可能就是这种情况),则必须提供自己的运算符newdelete。在最简单的情况下,您可以简单地包装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);
}

如果您正在为一个普通的托管平台进行编译,那么您永远不应该这样做,所以如果您确实需要这样做,您最好熟悉平台上内存管理的复杂性。

答案 2 :(得分:9)

我会引用文档,因为他们说得更好。

  

编写C ++

     

如果包含,可以用C ++编写AVR平台的程序   配置avr-gcc时启用语言的c ++。只是   关于写作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 ++好东西都习以为常   如果没有工作,那么编程是值得的   C ++中的AVR。构造函数和析构函数功能齐全   使用类和面向对象的组织优势   编程可能使C ++成为一个很好的选择。

答案 3 :(得分:4)

如果你只是想做一个界面,你不需要新的/删除。只需从基类析构函数中删除“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

进行编译