祝你好运, Angus #ifndef FWD_DECLARABLE_STRING_H #define FWD_DECLARABLE_STRING_H > #include< string> struct String:public std :: string { typedef std :: string base_type; String(){} String(base_type const& other) :base_type(other){} explicit String(allocator_type const& al) :base_type(al){} String(String const& other,size_type off,size_type count = npos ) :base_type(其他,关闭,计数){} 字符串(字符串const& other,size_type off,size_type count, allocator_type const& al) :base_type(other,off,count,al){} String(value_type const * ptr,size_type count) :base_type(ptr,count){} String(value_type const * ptr,size_type count,allocator_type const& al) :base_type(ptr,count,al){} String(value_type const * ptr) :base_type(ptr){ } $ / $ String(value_type const * ptr,allocator_type const& al) :base_type(ptr,al){} String(size_type count,value_type ch) :base_type(count,ch){} 字符串(size_type count,value_type ch,allocator_type const& al) :base_type(count,ch,al){} 模板< typename InIt> 字符串(首先是InIt,最后是InIt) :base_type(first,last){} template< typename InIt> String(InIt first,InIt last,allocator_type const& al) :base_type(first,last,al){} String& operator =(value_type const * ptr) {base_type :: operator =(ptr); } String& operator =(value_type ch) {base_type :: operator =(ch); } }; #endif // FWD_DECLARABLE_STRING_H #include< iostream> int main() { String const angus =" angus"; std :: string const jmarc =" jmarc"; String test1; std :: string test2; //分配标准::字符串到字符串 test1 = jmarc; std :: cout<< test1 << test1<< std :: endl; //将字符串分配给std :: string test2 = angus; std: :cout<< test2 << test2<< std :: endl; //将字符串赋给字符串(隐式赋值运算符) test1 = angus; std :: cout<< test1 << test1<< std :: endl; //隐式复制c-tor; 字符串const test3 = angus; std :: cout<< test3 << test3<< std :: endl; //从字符串复制构造std :: string std :: string test4 = angus; std :: cout<< test4 << test4<< std :: endl; 返回0; } 解决方案 Angus Leeming< an *********** @ btopenworld.com>写道: 你好, 有人可以向我解释为什么标准召集人选择输入stde :: std :: string而不是从std派生出来:: basic_string< char,...>? 结果当然是实际上无法转发声明 std :: string。 (是的,我知道有些库有一个string_fwd.h标题,但这不是便携式的。) 那就是说,有什么理由我无法得到一个否则是空的来自std :: string的字符串类? 有两个问题。 (a)没有虚拟析构函数。这意味着当指向的对象实际上是一个 derived_from_string时,你不能安全地调用删除 a指向字符串的指针。 (b)它不是为多态性而设计的。 (像大多数标准的 库一样。)公共继承通常用于 多态。注意(a)是(b)的症状。 如果你以某种方式知道你永远不会使用derived_from_string 多态,你就赢了''遇到问题。 但是,在继续之前,尝试使用私有继承和 几个使用良好的使用语句。这更安全。 会有任何隐藏的惊喜吗? 见上文。此外,如果人们*可以*使用你的 derived_from_string类型进行多态使用,他们经常会这样做。 据我所知,String没有成员变量这一事实它本身意味着非虚拟std :: string析构函数不是问题。 [snip] 这与它无关。在指向字符串的指针上调用delete 是未定义的行为,如果它实际上指向 derived_from_string,无论derived_from_string是否具有 成员变量它本身。 " Angus Leeming" <一个*********** @ btopenworld.com>在消息新闻中写道:bj ********** @ hercules.btinternet.com ... 那就是说有什么真正的理由吗我不能从std :: string派生出一个空的 String类?会有隐藏的惊喜吗?正如我理解的那样,String没有自己的成员变量这一事实意味着非虚拟std :: string析构函数不是问题。 是什么让你觉得这不是问题?从没有虚拟析构函数的指向其基类的指针中删除a派生对象是未定义的行为。 导出的析构函数不是没关系做什么或那个 在派生类中没有数据成员。 Ron Natalie写道: Angus Leeming <一个*********** @ btopenworld.com>在消息中写道新闻:bj ********** @ hercules.btinternet.com ... 那说,有没有为什么我不能从std :: string派生一个空的 String类?会有隐藏的惊喜吗?正如我理解的那样,String没有自己的成员变量意味着非虚拟std :: string析构函数不是问题。 析构函数的指向其基类的指针中删除派生对象是未定义的行为。导出的析构函数不做任何事情或派生类中没有数据成员都没关系。 非常感谢对你们两个人的清楚解释。我将把你的 参数提交给项目主持人,他们会立即启动我建议的使用 String触摸;-) 再次感谢, Angus Hello,Could someone explain to me why the Standard conveners chose to typedefstd::string rather than derive it from std::basic_string<char, ...>?The result of course is that it is effectively impossible to forward declarestd::string. (Yes I am aware that some libraries have a string_fwd.h header,but this is not portable.)That said, is there any real reason why I can''t derive an otherwise emptyString class from std::string? Will there be any hidden surprises? As Iunderstand it, the fact that String has no member variables of its own meansthat the non-virtual std::string destructor is not an issue.Nonetheless, I''m wary because I have heard so much about ''std::string is notdesigned to be derived from''. Nobody has explained the rationale behind sucha statement to me however.Below is sample code that appears to work just fine.Best regards,Angus#ifndef FWD_DECLARABLE_STRING_H#define FWD_DECLARABLE_STRING_H#include <string>struct String : public std::string {typedef std::string base_type;String() {}String(base_type const & other): base_type(other) {}explicit String(allocator_type const & al): base_type(al) {}String(String const & other, size_type off, size_type count = npos): base_type(other, off, count) {}String(String const & other, size_type off, size_type count,allocator_type const & al): base_type(other, off, count, al) {}String(value_type const * ptr, size_type count): base_type(ptr, count) {}String(value_type const * ptr, size_type count, allocator_type const & al): base_type(ptr, count, al) {}String(value_type const * ptr): base_type(ptr) {}String(value_type const * ptr, allocator_type const & al): base_type(ptr, al) {}String(size_type count, value_type ch): base_type(count, ch) {}String(size_type count, value_type ch, allocator_type const & al): base_type(count, ch, al) {}template <typename InIt>String(InIt first, InIt last): base_type(first, last) {}template <typename InIt>String(InIt first, InIt last, allocator_type const & al): base_type(first, last, al) {}String & operator=(value_type const * ptr){ base_type::operator=(ptr); }String & operator=(value_type ch){ base_type::operator=(ch); }};#endif // FWD_DECLARABLE_STRING_H#include <iostream>int main(){String const angus = "angus";std::string const jmarc = "jmarc";String test1;std::string test2;// Assign a std::string to a Stringtest1 = jmarc;std::cout << "test1 " << test1 << std::endl;// Assign a String to a std::stringtest2 = angus;std::cout << "test2 " << test2 << std::endl;// Assign a String to a String (implicit assignment operator)test1 = angus;std::cout << "test1 " << test1 << std::endl;// Implicit copy c-tor;String const test3 = angus;std::cout << "test3 " << test3 << std::endl;// Copy construct a std::string from a Stringstd::string test4 = angus;std::cout << "test4 " << test4 << std::endl;return 0;} 解决方案 Angus Leeming <an***********@btopenworld.com> writes: Hello, Could someone explain to me why the Standard conveners chose to typedef std::string rather than derive it from std::basic_string<char, ...>? The result of course is that it is effectively impossible to forward declare std::string. (Yes I am aware that some libraries have a string_fwd.h header, but this is not portable.) That said, is there any real reason why I can''t derive an otherwise empty String class from std::string?There are two issues.(a) No virtual destructor. This means you can''t safely call delete ona pointer to string when the object pointed to is in fact aderived_from_string.(b) It isn''t designed for polymorphism. (Like most of the standardlibrary.) Public inheritance is usually used forpolymorphism. Note (a) is a symptom of (b) .If you somehow know you''ll never use the derived_from_stringpolymorphically, you won''t encounter problems.However, before proceeding, try private inheritance combined with afew well-placed using statements. That is safer. Will there be any hidden surprises?See above. Further, if people *can* make polymorphic use of yourderived_from_string type, they all too often will. As I understand it, the fact that String has no member variables of its own means that the non-virtual std::string destructor is not an issue.[snip]This has nothing to do with it. Calling delete on a pointer to stringis undefined behavior if it in fact points to aderived_from_string, regardless of whether derived_from_string hasmember variables of its own."Angus Leeming" <an***********@btopenworld.com> wrote in message news:bj**********@hercules.btinternet.com... That said, is there any real reason why I can''t derive an otherwise empty String class from std::string? Will there be any hidden surprises? As I understand it, the fact that String has no member variables of its own means that the non-virtual std::string destructor is not an issue.What makes you think it''s not an issue? It is undefined behavior to deletea derived object from a pointer to its base class without a virtual distructor.It doesn''t matter that the derived destructor doesn''t do anything or that thereare no data members in the derived class. Ron Natalie wrote: "Angus Leeming" <an***********@btopenworld.com> wrote in message news:bj**********@hercules.btinternet.com... That said, is there any real reason why I can''t derive an otherwise empty String class from std::string? Will there be any hidden surprises? As I understand it, the fact that String has no member variables of its own means that the non-virtual std::string destructor is not an issue. What makes you think it''s not an issue? It is undefined behavior to delete a derived object from a pointer to its base class without a virtual distructor. It doesn''t matter that the derived destructor doesn''t do anything or that there are no data members in the derived class.Many thanks to both of you for the clear explanation. I shall put yourarguments to the project moderator who will promptly boot my proposed use ofString into touch ;-)Thanks again,Angus 这篇关于class String:public std :: string {}; ????的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持! 上岸,阿里云!