22

私は 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 のデストラクタを仮想かどうかに関係なく定義すると、他にもさまざまな同様のエラーが発生します。私が初心者として見落としているのは単純な問題だと確信しています。

また、Windows で avr-g++ を使用して、AVR チップ用にこれを書いています。

ありがとう

4

4 に答える 4

38

古いスレッドに投稿して申し訳ありませんが、Google の検索結果ではまだかなり上位にあります。この問題が発生した場合は、このリンクを確認する必要があります。なぜなら、-lstdc++ をリンクする必要があるだけで、これで問題が解決したからです。私にとっての問題。

次の行は、そのように強調表示せずにコミュニティによって追加されました。私を逃れる理由で私の回答にコメントを追加する代わりに、「または、g++ などの -lstdc++ オプションを暗黙的に追加する C++ コンパイラを使用してください。」

于 2015-03-26T17:25:34.317 に答える
18

なんらかの理由で標準ライブラリにリンクしていない場合 (埋め込みシナリオの場合など)、独自の演算子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);
}

通常のホストされたプラットフォーム用にコンパイルする場合は、これを行う必要はありません。そのため、これを行う必要がある場合は、プラットフォームでのメモリ管理の複雑さに精通している必要があります。

于 2011-08-10T17:53:33.733 に答える
10

ドキュメントの方が優れているので、ドキュメントを引用します。

C++ の作成

avr-gcc の構成中に有効な言語に c++ を含めた場合、C++ で AVR プラットフォーム用のプログラムを作成できます。「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++ が優れた選択肢になる可能性があります。

于 2011-08-10T17:58:21.000 に答える
5

インターフェイスを作成するだけの場合は、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

于 2012-11-17T01:53:53.330 に答える