首先是我的代码布局:
A.H
class STORAGE_CLASS_DECLARATOR A : public PureVirtual
{
some member functions, all working;
void someFunctionCallingOperator<<();
friend std::ostream& operator << (std::ostream &, A *);
}
A.cpp
std::ostream& operator << (std::ostream & out, A * a){...}
void A::someFunctionCallingOperator<<(){...}
其中Storage_xxx_declarators是declspec的宏。我已经尝试过使用和不使用声明器的朋友函数都无济于事。
我在运算符上得到一个未解析的外部符号&lt;&lt;功能
根据我的理解,这可能是由于:
我意识到链接是一个单独的阶段,我必须做一些非常简单的错误,但我现在已经盯着看了一段时间,并且无法从理论上推断出为什么会发生这种情况,所以我转向SO寻求帮助< / p>
谢谢你, AK
答案 0 :(得分:3)
根据您的评论,我认为您的设置是这样的:
A.H
namespace NN {
class STORAGE_CLASS_DECLARATOR A : public PureVirtual
{
some member functions, all working;
void someFunctionCallingOperator<<();
friend std::ostream& operator << (std::ostream &, A *);
}
}
A.cpp:
using namespace NN;
std::ostream& operator << (std::ostream & out, A * a){...}
void A::someFunctionCallingOperator<<(){...}
这是一个非常常见的设置,但我不鼓励任何人使用它,因为它会导致您现在拥有的类型问题。让我们看看A.cpp
中发生了什么:
在解析A::someFunctionCallingOperator
的定义时,全局命名空间中没有A
,因此会考虑using
- ed名称空间,而A
将被解析为NN::A
}。
然而,在解析operator<<
的定义时,什么都没有表明应该将运算符放入名称空间NN
。所以这很高兴地定义了全局命名空间中的operator<<
,它与NN::operator<<
中的朋友声明引入的{{1>} 绝不相关。稍后,当您在A.h
内使用<<
时,someFunctionCallingOperator
(已在NN::operator<<
中声明)通过参数依赖查找找到,因此使用它。最后,链接器正在抱怨它从未定义过。
解决此问题的正确方法是在A.h
中停止using namespace NN
并将内容正确地包含在命名空间中,就像在头文件中一样:
A.cpp
答案 1 :(得分:1)
简答:确保运算符的返回类型和参数在定义和实现方面都是相同的。
答案稍长:
您似乎省略了运算符的返回类型。您的朋友函数定义包含您的宏,但实现标识ostream&
的返回类型。如果您的宏中未包含ostream&
,则可能会导致无法解析的外部符号错误。
您还省略了实现中的参数,如果您尝试将运算符与参数一起使用(这对<<
来说是正常的),也会导致未解决的外部符号错误。编译器将使用单个参数(以及<<
返回类型)查找ostream&
的实现,但只会找到带有空参数列表的operator<<
的实现。
答案 2 :(得分:0)
我通过将方法放在同一名称空间
中来解决问题