C++ 重载运算符<< 通过使用静态辅助方法创建访问冲突错误
C++ Overloading Operator<< By Using Static Helper Methods Creating Access Violation Error
我有一个叫 Bill
的 class。在 class 的属性中,有一个名为 category
的 int
类型。
打印帐单时,应显示类别名称而不是编号。所以我写了这个静态辅助函数来将 category
整数转换为相应的字符串:
// Takes an integer representing the category and returns its corresponding name
static const std::string& getCategoryByNumber(int category)
{
switch (category)
{
case 1:
return "Food";
case 2:
return "Gift";
case 3:
return "Fuel";
case 4:
return "Electricity";
case 5:
return "Clothes";
case 6:
return "Holidays";
case 7:
return "Water";
case 8:
return "Fees";
default:
exit(1);
}
}
现在我尝试在 Bill
class 定义之外重载 operator<<
,如下所示:
std::ostream& operator<<(std::ostream& os, Bill& bill) {
int category = bill.getCategory();
const std::string& nameOfCategory = getCategoryByNumber(category);
std::cout << nameOfCategory.c_str();
return os;
}
创建bill类型的对象时出现错误,运行这行代码:
cout << billObject;
如果这些信息还不够,我很乐意添加更多信息。
我该如何解决这个错误,是什么原因造成的?
我对这里真正发生的事情的猜测是,编译器在 getCategoryByNumber
函数的上下文中从 C 字符串创建一个 std::string
对象,returns 对它的引用,并且一旦函数returns.
,它引用的对象就会立即被删除
请考虑从 getCategoryByNumber
返回 const char*
或 std::string
而不是 std::string&
。
编译器应该警告过你 "returning reference to local object" 或类似的(如果你打开所有警告,你总是应该)。您还应该避免调用 exit()
,而是 throw
一个异常,让应用程序有机会恢复
struct Bill
{
/* ... */
int GetCategory() const;
static string GetCategoryName(int category)
{
switch (category) {
default: throw std::runtime_error("Bill: category '"+
std::to_string(category)+"' unknown");
case 1: return "Food";
case 2: return "Gift";
case 3: return "Fuel";
case 4: return "Electricity";
case 5: return "Clothes";
case 6: return "Holidays";
case 7: return "Water";
case 8: return "Fees";
}
}
};
inline
std::ostream& operator<<(std::ostream&os, Bill const&bill)
{
return os << Bill::GetCategoryName(bill.GetCategory());
}
我有一个叫 Bill
的 class。在 class 的属性中,有一个名为 category
的 int
类型。
打印帐单时,应显示类别名称而不是编号。所以我写了这个静态辅助函数来将 category
整数转换为相应的字符串:
// Takes an integer representing the category and returns its corresponding name
static const std::string& getCategoryByNumber(int category)
{
switch (category)
{
case 1:
return "Food";
case 2:
return "Gift";
case 3:
return "Fuel";
case 4:
return "Electricity";
case 5:
return "Clothes";
case 6:
return "Holidays";
case 7:
return "Water";
case 8:
return "Fees";
default:
exit(1);
}
}
现在我尝试在 Bill
class 定义之外重载 operator<<
,如下所示:
std::ostream& operator<<(std::ostream& os, Bill& bill) {
int category = bill.getCategory();
const std::string& nameOfCategory = getCategoryByNumber(category);
std::cout << nameOfCategory.c_str();
return os;
}
创建bill类型的对象时出现错误,运行这行代码:
cout << billObject;
如果这些信息还不够,我很乐意添加更多信息。 我该如何解决这个错误,是什么原因造成的?
我对这里真正发生的事情的猜测是,编译器在 getCategoryByNumber
函数的上下文中从 C 字符串创建一个 std::string
对象,returns 对它的引用,并且一旦函数returns.
请考虑从 getCategoryByNumber
返回 const char*
或 std::string
而不是 std::string&
。
编译器应该警告过你 "returning reference to local object" 或类似的(如果你打开所有警告,你总是应该)。您还应该避免调用 exit()
,而是 throw
一个异常,让应用程序有机会恢复
struct Bill
{
/* ... */
int GetCategory() const;
static string GetCategoryName(int category)
{
switch (category) {
default: throw std::runtime_error("Bill: category '"+
std::to_string(category)+"' unknown");
case 1: return "Food";
case 2: return "Gift";
case 3: return "Fuel";
case 4: return "Electricity";
case 5: return "Clothes";
case 6: return "Holidays";
case 7: return "Water";
case 8: return "Fees";
}
}
};
inline
std::ostream& operator<<(std::ostream&os, Bill const&bill)
{
return os << Bill::GetCategoryName(bill.GetCategory());
}