我真的希望能够从我正在编写的std::string
对象中分配一个DecoratedString
对象。
class DecoratedString
{
private:
std::string m_String;
public:
DecoratedString(const std::string& initvalue)
: m_String(initvalue)
{
}
const std::string& ToString() const
{
return m_String;
}
const std::string& operator=(const DecoratedString& rhs)
{
return rhs.ToString();
}
}
我已经编写了一个单元测试来确保其有效:
void DecoratedStringTest::testAssignmentToString()
{
std::string expected("test");
DecoratedString sut(expected);
std::string actual;
actual = sut;
CPPUNIT_ASSERT_EQUAL(actual, sut.ToString());
}
然而,编译器说error: no match for 'operator=' in 'actual = sut'
。然后它列出了标准库中重载的operator =选项。
为什么编译器找不到我定义的 operator=
?
修改
所以我想我需要转换运算符,而不是赋值运算符。非常感谢那些看到我想要做的事的人,并解释了我应该做些什么。
答案 0 :(得分:2)
运算符=您已定义用于将装饰字符串分配给其他装饰字符串并从该分配返回std :: string。
你想要的是一个成员“转换运算符”,它会在需要时自动将修饰的字符串转换为std :: string,如下所示:
operator std::string const &() const { return ToString(); }
每当需要时,也会将装饰字符串自动转换为std::string const &
(即与std :: string进行比较,或者将DecoratedString传递给采用std::string const &
的函数时)。
答案 1 :(得分:1)
编译器抱怨这一行:
actual = sut;
应该是:
actual = sut.ToString();
或者你应该提供一个强制转换运算符来隐式转换DecoratedString
到std::string
:
class DecoratedString
{
...
operator std::string() const
{
return ToString();
}
};
答案 2 :(得分:1)
你倒退了。需要在operator=
上定义std::string
才能接受您的对象,而不是您要分配的类,但是因为您正在处理标准库不能这样做。
另一种选择是流操作符(作为自由函数):
std::string& operator<<( std::string& out, const your_class& yc )
{
out.assign( yc.to_string());
return out;
}
your_class myobj;
std::string str;
str << myobj;
或者只定义std::ostream
的常规流式传输并使用std::stringstream
。
正如其他人所指出的,另一个选择是类型转换运算符:
your_class::operator const std::string() const;
现代实践虽然告诉我们这不是最好的主意(临时,额外的副本,惊喜)。
答案 3 :(得分:1)
您正在重载用于将特定类型分配给DecoratedString
的一元赋值运算符,并且应该返回对DecoratedString
的引用,以便您可以链接赋值。此运算符的设计不允许您将DecoratedString
的对象分配给不同的数据类型,而是可以将DecoratedString
的对象分配给DecoratedString
。它还为您提供了一个定义明确的函数来处理您的类的赋值可能需要的任何类型的特定处理(例如,深层复制)。
您必须致电ToString()
功能,否则您必须创建一个转换运算符,通过为{{实现以下成员函数,将DecoratedString
转换为std::string
1}}:
DecoratedString
这可能是也可能不是一个好主意,因为编译器将隐式使用此转换运算符,并可能导致意外行为。
另外,运算符重载不起作用的另一个原因是你试图通过返回值重载函数,这在C ++中是一个很大的禁忌。