3

ヘッダー ファイル dlist.h の一部は、次のように定義されています。

#ifndef __DLIST_H__
#define __DLIST_H__
#include <iostream>

class emptyList {};

template <typename T>
class Dlist {
 public:
    bool isEmpty() const;

 private:
    struct node {
    node   *next;
    node   *prev;
    T      *o;
    };

    node   *first; // The pointer to the first node (NULL if none)
    node   *last;  // The pointer to the last node (NULL if none)
};

#include "dlist.cpp"
#endif

次のような dlist.cpp ファイルを作成すると:

#include "dlist.h"

template <typename T>
bool Dlist<T>::isEmpty() const
{
    return !first and !last;
}

4 行目でエラー メッセージが表示されます: 「bool Dlist::isEmpty() const」の再定義

を削除する#include "dlist.h"と、4 行目でエラーが発生します: expected initializer before '<' トークン

ここで何か助けはありますか?dlist.h ファイルから関数を定義することを許可していない、何か間違っていることがありますか? ありがとうございました。

4

5 に答える 5

7

クラステンプレートのメンバー関数の実装は、ヘッダーファイルまたはヘッダーに含まれるファイルに配置する必要があります。コンパイラは、特定のタイプのテンプレートをインスタンス化するために、このコードにアクセスする必要がありますT

あなたの場合、問題はヘッダーをに含めていることであり.cpp、その逆も同様です。宣言と実装を別々のファイルに保存したい場合は、実装のサフィックスを別のファイルに変更することをお勧めし.cppます.icpp。一部のビルドシステムは、接尾辞が付いたものからオブジェクトファイルをコンパイルしようとする場合が.cppあり、これもエラーになります。

  1. から削除#include "dlist.h"dlist.cppます。
  2. (オプション)名前を.などに変更dlist.cppしますdlist.icpp。なんで?.cpp多くのビルドシステムは、末尾がオブジェクトファイルであるファイルを自動的にコンパイルするためです。.cppまた、多くのプログラマーは、ファイルオブジェクトファイルにコンパイルされると想定しています。
  3. (ステップ2が実行された場合のみ)現在行われているようdlist.icppに、に名前が変更されたものを含めます。dlist.hdlis.cpp
于 2012-12-01T10:48:55.790 に答える
2

ヘッダー ファイルは自分用に定義されています。変更することはできません。

#include "dlist.h"次に、からディレクティブを削除する必要があります.cpp(既にに入っ dlist.hているため、循環依存関係が作成されているため)。与えられたヘッダーがばかげているため、すべてが完全に逆になります。

A.cppは であってはなりませ#included。通常、テンプレート関連の定義を独自のファイルに分割する必要がある場合は、別の拡張子が必要ですこの義務をあなたに課した人物と話し、彼らのヘッダーがばかげていて、紛らわしく、型にはまらないものであることを説明することを強くお勧めします。

于 2012-12-01T10:59:22.343 に答える
1

#include "dlist.cpp"ヘッダーファイルで使用する代わりに、関数定義をに移動しますdlist.h

于 2012-12-01T10:48:24.123 に答える
1

.cpp ファイルを .h ファイルに含めるのはなぜですか? 99% の場合、それを行うべきではありません。

コードを追加するだけ

template <typename T>
bool Dlist<T>::isEmpty() const
{
    return !first and !last;
}

.cpp ファイルの include ディレクティブの代わりに。

于 2012-12-01T10:51:50.537 に答える
0

を削除し、#include "dlist.h"dlist.cpp自体をコンパイルしないでください。

次のようなものを使用することもできます

dlist.hにはdlist.cppが含まれ、次のように定義されているためです__DLIST_H__

#define __DLIST_H__

dlist.cppを次のように変更できます

#ifdef __DLIST_H__

template <typename T>
bool Dlist<T>::isEmpty() const
{
    return !first and !last;
}

#endif

このようにして、dlist.cppをコンパイルしようとしても、コンパイラエラーは発生しません。しかし、私は他の答えと同じように、このファイルに.cppという名前を付けない方がよいでしょう。

于 2012-12-01T10:50:54.033 に答える