c++ - 在哪里声明结构运算符重载
问题描述
我是 C++ 的新手(我来自 C#)。
我在命名空间中有这个结构:
#pragma once
namespace utils {
struct astTime
{
int hour;
int min;
double secs;
};
double round(double number, int decPlace);
}
我还有一个实现round
功能的源文件。
为了在 Boost 测试中使用该结构,我在 boost 测试文件 (.cpp) 中定义了这两个运算符:
namespace utils {
bool operator ==(utils::astTime const &left, utils::astTime const &right)
{
return(
left.secs == right.secs
&& left.min == right.min
&& left.hour == right.hour);
}
std::ostream& operator<<(std::ostream& os, const utils::astTime& dt)
{
os << dt.hour << "h " << dt.min << "m " << dt.secs << "s" << std::endl;
return os;
}
}
我必须在哪里声明这两个运算符(以及如何声明)?
我已将其移至头文件(因为我不知道在哪里声明它),将它们从 boost 测试源文件中删除,这样:
#pragma once
#include <iostream>
namespace utils {
struct astTime
{
int hour;
int min;
double secs;
};
bool operator ==(utils::astTime const &left, utils::astTime const &right)
{
return(
left.secs == right.secs
&& left.min == right.min
&& left.hour == right.hour);
}
std::ostream& operator<<(std::ostream& os, const utils::astTime& dt)
{
os << dt.hour << "h " << dt.min << "m " << dt.secs << "s" << std::endl;
return os;
}
double round(double number, int decPlace);
}
我收到以下错误:
警告 LNK4006: "class std::basic_ostream > & __cdecl utils::operator<<(class std::basic_ostream > &,struct utils::astTime const &)" (??6utils@@YAAAV?$basic_ostream@DU?$ char_traits@D@std@@@std@@AAV12@ABUastTime@0@@Z) 已经在 Utils.obj 中定义;第二个定义被忽略
解决方案
通常,在编写类时,您会在与该类相同的标头和命名空间中声明所有运算符。这允许类的所有用户在类的对象上使用相同的运算符集。这条规则可能有例外(例如,将 IO 运算符放在单独的头文件中以减少编译时间),但一般的经验法则是成立的。
您是否还在标题中定义运算符是一个单独的问题。通常,当它们是轻量级的并且需要在调用站点内联时,您会在标题中提供定义。此外,如果运算符是模板,您通常会在标题中提供定义。
您的链接器错误是因为您的运算符定义位于标头中,该标头包含在多个翻译单元(.cpp 文件)中。实际上,这意味着定义在包含程序的多个翻译单元中重复,这违反了ODR。要解决此问题,您可以用 标记运算符inline
,这将允许编译器在最终程序中仅使用多个定义之一(以防它未在每个调用站点中内联)。
推荐阅读
- web-scraping - Google Sheets =IMPORTHTML 在加载时运行,然后“无法获取 url”
- r - 创建月度趋势线图,将值的计数作为 y 变量
- listview - 尝试从嵌套列表视图访问父列表视图中的控件
- c - GDB 是否检查命令反转字节?
- c# - 实体框架失去了我的领域的价值
- git - git reset --hard HEAD 与。git reset --hard
- reactjs - 自定义 React-Color 组件在更新颜色时中断
- linux - GitLab CI 遇到错误:找不到命令:ajv
- c - ping 时 strace 输出中 connect() 上的 EINVAL
- swagger - 使用文件格式的 Swagger 上传文件?