我知道std::string is not designed for inheritance,但是,我想知道为什么这个类定义不能编译:
using std::string;
class ExtendedString: public string
{
public:
using string::string;
ExtendedString left(size_type n) const {
return substr(0, n>size()?size():n);
}
};
我得到这个错误:
../../src/capel-tool.cpp:21:17: error: could not convert ‘std::__cxx11::basic_string<_CharT, _Traits, _Alloc>::substr(std::__cxx11::basic_string<_CharT, _Traits, _Alloc>::size_type, std::__cxx11::basic_string<_CharT, _Traits, _Alloc>::size_type) const [with _CharT = char; _Traits = std::char_traits<char>; _Alloc = std::allocator<char>; std::__cxx11::basic_string<_CharT, _Traits, _Alloc>::size_type = long unsigned int](0, ((n > ((const ExtendedString*)this)->ExtendedString::<anonymous>.std::__cxx11::basic_string<char>::size()) ? ((const ExtendedString*)this)->ExtendedString::<anonymous>.std::__cxx11::basic_string<char>::size() : n))’ from ‘std::__cxx11::basic_string<char>’ to ‘ExtendedString’
我期望left
函数使用std::string中的任何默认构造函数。
即使我像这样添加一个显式的构造函数:
using std::string;
class ExtendedString: public string
{
public:
using string::string;
ExtendedString left(size_type n) const {
return substr(0, n>size()?size():n);
}
explicit ExtendedString(const std::string &s);
};
我仍然得到同样的错误。
只有当我添加一个普通构造函数时:
using std::string;
class ExtendedString: public string
{
public:
using string::string;
ExtendedString(const std::string &s);
ExtendedString left(size_type n) const {
return substr(0, n>size()?size():n);
}
};
代码编译OK。
现在假设我想对一个为继承而设计的类做同样的事情。我能不能只创建这种 Package 器的方式,类可以互换使用,而不需要创建构造函数,而将创建和调用,而不仅仅是“语法糖”
编辑1:
这个suggested question确实解释了为什么我的代码不起作用,但它并没有像公认的问题那样提出任何替代方案。
2条答案
按热度按时间ne5o7dgx1#
代码的问题是
substr
返回std::string
,而不是ExtendedString
。类型之间不存在隐式转换,因此无法编译return语句。在继承层次结构中有一个隐式转换,即您可以将ExtendedString
转换为std::string
,但不能反过来。要解决这个问题,只需使用
left
函数:ExtendedString(const std::string&)
return ExtendedString(substr(...))
然而,一般来说,你试图做的事情在C中是不可能的。从
std::string
继承的每个成员函数都不会返回ExtendedString
,所以你有错误的接口。C没有给你定义 * 扩展方法 * 的方法,这是你模仿的特性。“Clean” 可选
std::string
到ExtendedString
的隐式转换,但这会导致不必要的复制ExtendedString(const std::string &s);
时所做的std::string
私有继承,或者更好,将其 Package 为成员std::string
拥有的每个成员函数创建 Package 器函数,并使它们在必要时接受/返回ExtendedString
尽管有时调用
str.function()
有时调用function(str)
很烦人,但与任何替代方案相比,这种不一致性的代价很小。qnyhuwrf2#