使用char*运算符的随机输出 我有C++类,我想打印一个对象,所以我创建了一个char * CAST操作符。由于某种原因,运算符函数的输出是随机符号,而不是返回的字符串。 代码如下: operator const char*()const { std::cout << (std::to_string(Nom) + '/' + std::to_string(Denom)).c_str() << std::endl; return (std::to_string(Nom) + '/' + std::to_string(Denom)).c_str(); } 运算符常量char*()常量{ std::cout
使用char*运算符的随机输出 我有C++类,我想打印一个对象,所以我创建了一个char * CAST操作符。由于某种原因,运算符函数的输出是随机符号,而不是返回的字符串。 代码如下: operator const char*()const { std::cout << (std::to_string(Nom) + '/' + std::to_string(Denom)).c_str() << std::endl; return (std::to_string(Nom) + '/' + std::to_string(Denom)).c_str(); } 运算符常量char*()常量{ std::cout,c++,typecast-operator,C++,Typecast Operator,(std::to_string(Nom)+'/'+std::to_string(Denom))创建一个临时变量。c_str()获取该变量拥有的某些内存的地址 不久之后,该变量被销毁(您不会将其复制/移动到任何地方)。内存被释放 虽然从c_str()获得的地址保留了下来,但现在它指向的内存可能是应用程序的一部分,也可能不是应用程序的一部分。尝试读取此地址是未定义的行为(在本网站简称UB)。(std::to_string(Nom)+'/'+std::to_string(Denom))创建一个临时变量
(std::to_string(Nom)+'/'+std::to_string(Denom))
创建一个临时变量。c_str()获取该变量拥有的某些内存的地址
不久之后,该变量被销毁(您不会将其复制/移动到任何地方)。内存被释放
虽然从c_str()获得的地址保留了下来,但现在它指向的内存可能是应用程序的一部分,也可能不是应用程序的一部分。尝试读取此地址是未定义的行为(在本网站简称UB)。(std::to_string(Nom)+'/'+std::to_string(Denom))
创建一个临时变量。c_str()获取该变量所拥有的某些内存的地址
不久之后,该变量被销毁(您不会将其复制/移动到任何地方)。内存被释放
虽然从c_str()获得的地址保留了下来,但现在它指向的是一些内存,这些内存可能是应用程序的一部分,也可能不是应用程序的一部分。尝试读取这些内存是未定义的行为(在本站点简称UB)。代替返回一个管理内存的对象,而不是原始的
常量字符*
operator std::string () const {
std::stringstream ss;
ss << Nom << '/' << Denom;
return ss.str();
}
运算符std::string()常量{
std::stringstream-ss;
ss替换返回一个管理内存的对象,而不是原始const char*
operator std::string () const {
std::stringstream ss;
ss << Nom << '/' << Denom;
return ss.str();
}
运算符std::string()常量{
std::stringstream-ss;
ss其他答案的补充:通常隐式强制转换运算符是一种不好的样式。尤其是对与类的类型无关的类型的强制转换
如果要强制转换对象,更好的方法可能是显式强制转换:
class Rational
{
public:
...
std::string toString() const
{
return std::to_string(Nom) + '/' + std::to_string(Denom);
}
};
您可以使用它重载“out”函数:
std::ostream & operator <<(std::ostream &stream, const Rational &obj)
{
stream << obj.toString();
return stream;
}
std::ostream&operator其他答案的补充:通常隐式转换运算符是一种糟糕的样式。尤其是对与类的类型无关的类型的转换
如果要强制转换对象,更好的方法可能是显式强制转换:
class Rational
{
public:
...
std::string toString() const
{
return std::to_string(Nom) + '/' + std::to_string(Denom);
}
};
您可以使用它重载“out”函数:
std::ostream & operator <<(std::ostream &stream, const Rational &obj)
{
stream << obj.toString();
return stream;
}
std::ostream&operator你认为c_str()做什么?你在一个临时对象上调用c_str()
。结果是在操作符返回的那一刻,甚至在返回之前,指针就晃来晃去。原因是std::string
具有c_str()
而不是operator char*()
是为了更清楚地表明这样的代码犯了严重的错误。你认为c_str()有什么作用?你在一个临时对象上调用c_str()
。结果是在操作符返回的那一刻,甚至在返回之前,指针就悬空了。std::string
的原因是c_str()
而不是运算符char*()
是为了更清楚地表明这样的代码犯了严重错误。如果需要const char*运算符(而不是std::string),则保留字符串的副本作为类的成员,然后可以返回.c_Str()我会进一步建议将字符串设为mutable
成员,并添加一个可变的“statechanged”bool,这样就可以在不破坏类“const
正确性的情况下使用延迟计算和缓存。这允许您将字符串创建逻辑放入运算符中,这样,只有在第一次调用运算符时才会生成实际的代表字符串,并且仅在实例的状态自最后一个调用。如果需要const char*运算符(而不是std::string),则保留该字符串的一个副本作为类的成员,然后可以返回该类的.c_Str()。我进一步建议将该字符串设置为可变
成员,并添加可变的“state changed”bool,这样就可以在不破坏类“const
正确性的情况下使用延迟计算和缓存。这允许您将字符串创建逻辑放入运算符中,这样,只有在第一次调用运算符时才会生成实际的代表字符串,并且仅在实例的状态自最后一个电话。