1

正常にコンパイルされたクラス「Vector3」があります。これには、Vector3 が 2 番目のオペランドである場合に * および << 演算子をオーバーロードするなど、非フレンド関数とフレンド関数の両方が含まれています。問題は、演算子がオーバーロードされているかどうかに関係なく、フレンド関数のいずれにもリンクできないことです。したがって、エラーが演算子のオーバーロードに固有のものではないことを確認できます。リンクに使用する g++ コマンドは以下の通りです (末尾の Makefile も参照してください)。

g++ -Wall -W -I./ -g -o main.out main.o Vector3.o

次のエラーが発生しました。

main.cpp:7: undefined reference to `operator*(double, Vector3 const&)'
main.cpp:9: undefined reference to `mag(Vector3 const&)'
main.cpp:10: undefined reference to `operator<<(std::basic_ostream<char, std::char_traits<char> >&, Vector3 const&)'

以下は、ソース ファイル内の関連コードです。クラスごとに個別の .hpp と .cpp を作成するという慣例に従います。

/* file Vector3.hpp */
struct Vector3 {
    ...
    Vector3 operator*(const double k) const;
    friend Vector3 operator*(const double k, const Vector3 &vec);
    double magnitude() const;
    friend double mag(const Vector3 &vec);
    friend std::ostream& operator<<(std::ostream& output, const Vector3 &vec);
    ...
}

/* file Vector3.cpp */
Vector3 operator*(const double k, const Vector3 &vec) {
    ...
}

inline double mag(const Vector3 &vec) {
    ...
}

std::ostream& operator<<(std::ostream& output, const Vector3 &vec) {
    ...
}

/* file main.cpp */
#include "Vector3.hpp"
int main() {
    Vector3 M(1, 1, 1);
    M = M * 2.0;              // own operator* links successfully
    M = 10.0 * M;             // friend operator* doesn't link
    double m = M.magnitude(); // own function magnitude() links successfully
    double n = mag(M);        // friend function mag() doesn't link
    std::cout << M;           // friend operator<< doesn't link
}

最後に、これが私の Makefile です。

CXX         = g++
CXXFLAGS    = -Wall -W $(INCPATH) -g
INCPATH     = -I./
OBJS        = main.o Vector3.o

main.out: $(OBJS)
 $(CXX) $(CXXFLAGS) -o $@ $(OBJS) $(LIBPATH)

main.o: main.cpp
Vector3.o: Vector3.cpp

clean:
 rm -f $(OBJS) main.out

最も奇妙なことは、Vector3.cpp ファイルも main.cpp に含めてから、Makefile の OBJS から Vector3.o を削除すると、プログラムが正常にリンクすることです。私はこれを理解することはできません。私を助けてください!!

4

1 に答える 1

1

フレンド宣言が最初のパラメーターとして使用してoperator*いる間、フレンドの定義は使用します。これは、 が の typedef-name である場合にのみ、意図したとおりに機能します。本当に の略ですか? あなたが投稿したコードからはわかりません。fp_typedoublefp_typedoublefp_typedouble

問題magはかなり明らかですinline..cppファイルのように定義しました。インライン関数定義は、使用されるすべての場所で表示される必要があります。つまり、通常はヘッダー ファイルに配置する必要があります。

于 2009-12-28T02:17:37.770 に答える