链接至友元函数时出错

发布于 2024-08-16 21:27:19 字数 2082 浏览 4 评论 0原文

我有一个类“Vector3”,已成功编译。它包含非友元函数和友元函数,例如重载 * 和 <<当 Vector3 是第二个操作数时的运算符。问题是我无法链接到任何友元函数,无论是否运算符重载。所以我可以确认该错误不是特定于运算符重载的。用于链接的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

最奇怪的是,如果我在 main.cpp 中也包含 Vector3.cpp 文件,然后从 Makefile 中的 OBJS 中删除 Vector3.o,则程序链接成功。我无法理解这一点。请帮我!!

I have a class 'Vector3' which is compiled successfully. It contains both non-friend and friend functions, for example, to overload * and << operators when Vector3 is the second operand. The problem is I can't link to any of the friend functions, be it operator overloaded or not. So I can confirm that the error is not specific to operator overloading. The g++ command used for linking is as follows (please also see Makefile at the end),

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

which gave the following errors,

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&)'

Below is the relevant code in my source files. I follow the practice of making separate .hpp and .cpp for every class.

/* 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
}

Finally, this is my 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

The strangest thing is that if I include the Vector3.cpp file as well in main.cpp and then remove Vector3.o from OBJS in Makefile, the program links successfully. I cannot make sense of this. Please help me!!

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

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

发布评论

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

评论(1

咿呀咿呀哟 2024-08-23 21:27:19

友元operator* 的定义使用fp_type,而友元声明使用double 作为第一个参数。仅当 fp_typedouble 的 typedef-name 时,这才会按预期工作。您确定fp_type实际上代表double吗?从你发布的代码中我看不到它。

mag 的问题相当明显:您在 .cpp 文件中将其定义为 inline 。内联函数定义必须在使用它们的任何地方都可见,这意味着通常它们应该放置在头文件中。

The definition of friend operator* uses fp_type while the friend declaration uses double as the first parameter. This will only work as intended if fp_type is a typedef-name for double. Are you sure fp_type actually stands for double? I can't see it from the code you posted.

The problem with mag is rather obvious: you defined it as inline in .cpp file. Inline function definitions have to be visible everywhere they are used, meaning that normally they should be placed in the header file.

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