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

发布于 2024-11-29 01:48:45 字数 733 浏览 3 评论 0原文

我是 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++。

谢谢

I'm new to C++ programming, but have been working in C and Java for a long time. I'm trying to do an interface-like hierarchy in some serial protocol I'm working on, and keep getting the error:

Undefined reference to 'operator delete(void*)'

The (simplified) code follows below:

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();
}

The constructor and nextByte functions are implemented in StringWriter.cpp, but nothing else. I need to be able to delete a StringWriter from a pointer to a PacketWriter, and i've been getting various other similar errors if I define a destructor for StringWriter, virtual or not. I'm sure it's a simple issue that I'm overlooking as a newbie.

Also, I'm writing this for an AVR chip, using avr-g++ on Windows.

Thanks

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

写给空气的情书 2024-12-06 01:48:45

很抱歉在旧帖子中发帖,但它在 Google 搜索结果中的排名仍然很高,如果您遇到此问题,您确实应该查看 这个链接,因为它说你只需要链接 -lstdc++ 这就是为我解决问题的方法。

社区添加了以下行,但没有突出显示它,而是出于我无法理解的原因只是在我的答案中添加了评论:
“或者使用将隐式添加 -lstdc++ 选项的 C++ 编译器,例如 g++。”

Sorry for posting in an old thread, but it's still pretty high in Google's search results and if you have this problem, you really should check out this link, because there it says that you simply need to link -lstdc++ and this is what solved the problem for me.

The following line was added by the Community without highlighting it as such and instead of just adding a comment to my answer for reasons that elude me:
"Or use a C++ compiler that will implicitly add the -lstdc++ option, e.g. g++."

鸵鸟症 2024-12-06 01:48:45

如果您由于某种原因没有链接到标准库(嵌入场景中很可能出现这种情况),则必须提供自己的运算符 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);
}

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

If you are not linking against the standard library for some reason (as may well be the case in an embedded scenario), you have to provide your own operators new and delete. In the simplest case, you could simply wrap malloc, or allocate memory from your own favourite source:

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);
}

You should never have to do this if you are compiling for an ordinary, hosted platform, so if you do need to do this, you better be familiar with the intricacies of memory management on your platform.

面如桃花 2024-12-06 01:48:45

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

编写 C++

如果包含的话,您可以用 C++ 为 AVR 平台编写程序
avr-gcc 配置期间启用的语言中的 c++。只是
关于编写 C AVR 程序部分中的所有内容均适用,因此
首先阅读该内容。

使用 C++ 的主要缺点是:

C++ 调用约定副作用
不支持 libstdc++。

C++ 调用约定副作用

某些 C++ 功能将自动生成隐式代码,如果
必需的,这会浪费宝贵的程序存储空间和处理器
时间。例如,如果在程序中的某个时刻有一个函数
按值传递 C++ 对象:

void myfunction(MyCppClass 对象);

您将最终生成一个默认的复制构造函数,并且
调用以创建 myfunction() 中使用的对象的临时副本。是
如果这不是您想要的,请小心:等效行为应该是
可以通过传递对常量 MyCppClass 对象的引用来实现,
同时避免代码和执行开销。

缺少 libstdc++ 和其他 C++ 功能

C++ 标准模板、类或函数都不是
可用的。另外,new和delete操作符还没有被
已实施。

还缺乏 C++ 异常支持。你可能需要做
请务必使用 -fno-exceptions 编译器选项来关闭
C++ 前端的异常。

有什么作用?尽管有很多你已经习惯的 C++ 好东西
无法使用,因此值得对
C++ 中的 AVR。构造函数和析构函数都是函数式的,只是
使用类和面向对象的组织优势
编程可能会让 C++ 成为一个不错的选择。

I will just quote the documentation, since they put it better.

Writing C++

You can write programs for the AVR platform in C++, if you included
c++ in the enabled-languages during configuration of avr-gcc. Just
about everything in the Writing C AVR programs section applies, so
read that first.

The major drawbacks of using C++ are:

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

C++ calling convention side-effects

Certain C++ features will automatically generate implied code if
required, which can waste valuable program memory space and processor
time. For instance, if at some point in the program a function is
passed a C++ object by value:

void myfunction(MyCppClass object);

You will wind up with a default copy constructor being generated and
called to create the temporary copy of object used in myfunction(). Be
careful if this isn't what you want: equivalent behavior should be
attainable by passing a reference to a constant MyCppClass object,
while avoiding the code and execution overhead.

Missing libstdc++ and other C++ features

None of the C++ standard templates, classes or functions are
available. In addition, operators new and delete have yet to be
implemented.

C++ exception support is also lacking. You'll probably need to make
sure to use the -fno-exceptions compiler option to turn off the
exceptions in the C++ front-end.

What does work? Even though lots of the C++ goodies you are accustomed
to working with aren't available, it can be worthwhile to program the
AVR in C++. Constructors and destructors are functional and just the
organizational advantages of using classes and object oriented
programming may make C++ a great choice.

祁梦 2024-12-06 01:48:45

如果你只是想做一个界面,你不需要new/delete。只需从基类析构函数中删除“虚拟”,并确保派生类具有以下实现
__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 进行编译

If you're just looking to do an interface, you don't need new/delete. Just remove the "virtual" from the base class destructor, and make sure the derived class has an implementation of
__cxa_pure_virtual().

Here is a compilable example. (I removed the returns to keep things simple, but it works just fine with them.)

In PacketWriter.h

class PacketWriter {
public:
    virtual void nextByte() = 0;
protected:
    ~PacketWriter() {}
};

In 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()
{
}

Compile with avr-g++ StringWriter.cpp

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文