3

クラステンプレートを使用して、独自のOrderedListデータ構造を実装しようとしています。CPPファイルの各コンストラクターと関数には、'{'を開くときにエラーがあります。エラーには、「以前にここで宣言されたFUNCTION_NAMEFUNTION_NAMEの再定義」と表示されます。

私は数人の同僚にそれを見てもらいましたが、役に立ちませんでした。これが私のファイルとエラーです:

CPPファイル"MyOrderedList.cpp"

#include "MyOrderedList.h"

template <class E>
MyOrderedList<E>::MyOrderedList() {/*IMPLEMENTATION*/}

template <class E>
MyOrderedList<E>::MyOrderedList(const MyOrderedList<E>& orig) { /*IMPLEMENTATION*/}

template <class E>
void MyOrderedList<E>::operator =(const MyOrderedList<E>& orig){/*IMPLEMENTATION*/}

template <class E>
MyOrderedList<E>::~MyOrderedList() {/*IMPLEMENTATION*/}

template <class E>
void MyOrderedList<E>::insert(E data){/*IMPLEMENTATION*/}

template <class E>
E MyOrderedList<E>::get(int pos) const{/*IMPLEMENTATION*/}

template <class E>
Node<E>* MyOrderedList<E>::getHead() const{/*IMPLEMENTATION*/}

template <class E>
MyOrderedList<E> MyOrderedList<E>::kLargest(int k) const{/*IMPLEMENTATION*/}

template <class E>
MyOrderedList<E> MyOrderedList<E>::operator +(const MyOrderedList<E>& list {/*IMPLEMENTATION*/}

Hファイル"MyOrderedList.h"

#ifndef MYORDEREDLIST_H
#define MYORDEREDLIST_H

#include <iostream>
#include <cstdlib>
#include "Node.h"

template <class E>
class MyOrderedList;
template <class E>
std::ostream& operator <<(std::ostream& out, const MyOrderedList<E>& list);

template <class E>
class MyOrderedList {
public:
    MyOrderedList();
    MyOrderedList(const MyOrderedList<E>& orig);
    void operator =(const MyOrderedList<E>& orig);
    virtual ~MyOrderedList();

    bool remove(E data);
    MyOrderedList<E> kLargest(int k) const;
    E get(int pos) const;
    void insert(E data);
    Node<E>* getHead() const;

    MyOrderedList<E> operator +(const MyOrderedList<E>& list);

    friend std::ostream& operator <<(std::ostream& out, const MyOrderedList<E>& list){/*IMPLEMENTATION*/}

private:
    Node<E>* head;
    int size;
};

#include "MyOrderedList.cpp"
#endif  //MYORDEREDLIST_H

Node.h

#ifndef NODE_H
#define NODE_H

#include <iostream>

template <class E>
class Node {
public:
    Node(const E& init_data = NULL, Node<E>* init_link = NULL){data = init_data; link = init_link;}
    Node(const Node<E>& orig);
    virtual ~Node();

    E getData() const{return data;}
    void setData(E newData);

    Node<E>* getLink(){return link;}
    void setLink(Node<E>* nextLink) {link = nextLink;}
private:
    E data;
    Node<E>* link;
};

#endif  /* NODE_H */

コンパイラエラー

MyOrderedList.cpp:12: error: redefinition of `MyOrderedList<E>::MyOrderedList()'
MyOrderedList.cpp:12: error: `MyOrderedList<E>::MyOrderedList()' previously declared here
MyOrderedList.cpp:19: error: redefinition of `MyOrderedList<E>::MyOrderedList(const MyOrderedList<E>&)'
MyOrderedList.cpp:19: error: `MyOrderedList<E>::MyOrderedList(const MyOrderedList<E>&)' previously declared here
MyOrderedList.cpp:42: error: redefinition of `void MyOrderedList<E>::operator=(const MyOrderedList<E>&)'
MyOrderedList.cpp:42: error: `void MyOrderedList<E>::operator=(const MyOrderedList<E>&)' previously declared here
MyOrderedList.cpp:77: error: redefinition of `MyOrderedList<E>::~MyOrderedList()'
MyOrderedList.cpp:77: error: `virtual MyOrderedList<E>::~MyOrderedList()' previously declared here
MyOrderedList.cpp:91: error: redefinition of `void MyOrderedList<E>::insert(E)'
MyOrderedList.cpp:91: error: `void MyOrderedList<E>::insert(E)' previously declared here
MyOrderedList.cpp:119: error: redefinition of `E MyOrderedList<E>::get(int) const'
MyOrderedList.cpp:119: error: `E MyOrderedList<E>::get(int) const' previously declared here
MyOrderedList.cpp:134: error: redefinition of `Node<E>* MyOrderedList<E>::getHead() const'
MyOrderedList.cpp:134: error: `Node<E>* MyOrderedList<E>::getHead() const' previously declared here
MyOrderedList.cpp:140: error: redefinition of `MyOrderedList<E> MyOrderedList<E>::kLargest(int) const'
MyOrderedList.cpp:140: error: `MyOrderedList<E> MyOrderedList<E>::kLargest(int) const' previously declared here
MyOrderedList.cpp:158: error: redefinition of `MyOrderedList<E> MyOrderedList<E>::operator+(const MyOrderedList<E>&)'
MyOrderedList.cpp:158: error: `MyOrderedList<E> MyOrderedList<E>::operator+(const MyOrderedList<E>&)' previously declared here
4

3 に答える 3

4

問題は、ヘッダーに関数の定義を含めていることです(間接的に。コンパイラがヘッダーを含むすべての変換単位でシンボルを生成して#include "MyOrderedList.cpp"いるため、関数は宣言されていないため、複数定義されたシンボルが得られます。inline

inlineこの問題の解決策の1つは、定義のように関数を宣言して、リンカーが重複を破棄できるようにすることです。定義を別のファイルに保持することは新しいことではありませんが、あまり一般的ではありません。一部の標準ライブラリ実装はそれを行います。ただし、混乱を避けるために、.cppの名前を別の名前に変更することを検討してください(ほとんどの人は、.cppは、コンパイルされることを意味し、含まれないことを意味すると思います)。

一方、もう少し単純化するには、.cppを完全に削除し、すべてを.hにする(すべての関数定義をとしてマークするinline)か、さらに一歩進んでクラス内の関数を定義することをお勧めします。定義inline。デフォルトであります。

于 2012-04-15T20:09:10.633 に答える
2

あなた.cpp.hファイル#includeはお互いに。なんで?

于 2012-04-15T19:46:32.637 に答える
0

テンプレートクラスの宣言と定義は一緒に保つ必要があります。これを行うためにファイルで使用#includeすることに問題はありませんが、ファイルにはヘッダーガード(つまりなど)も必要です。ただし、通常のアプローチは、すべてを同じファイル に押し込むことです。.cpp.cpp#ifndef MYORDEREDLIST_CPP.h

#include注-テンプレートクラス/関数は、.cppファイルを作成したり、ヘッダーファイルに定義を挿入したりする必要がある唯一の場合です。

于 2012-04-15T19:58:19.243 に答える