2013-12-11 65 views
2

最近,我一直想要定义一个std :: string的子类spstring。它在spstr.h声明:什么是继承std :: string的权利?

#include <cctype> 
#include <string> 
#include <algorithm> 
#include <sstream> 
#include <stdint.h> 
#include <xstring> 


class spstring : public std::string { 
public: 
    spstring(std::string s):std::string(s){} //Declare the constructor 
    int stoi(); //Declare stoi 
    spstring Spstring(std::string s); ////Declare mandatory conversion function 
}; 

spstring spstring::Spstring(std::string s) 
{ 
    spstring spstr(s); 
    return(spstr); 
} 

然而,当在main.cpp中测试:

spstring byteaddstr(std::string(argv[4])); //convertchar* to spstring 
int byteadd; 
byteadd=byteaddstr.stoi(); //call byteaddstr.stoi 

未能得到遵守的:

错误C2228:左“。 stoi“必须具有类/结构/联合

听起来很奇怪,因为byteaddstr确实是一个spstring的实例,为什么不能调用它的成员函数呢?

+7

您通常不希望从STL容器派生。 –

+2

一般来说,从std :: string'继承,尤其是public [(参见相关的SO post)]被认为是一个坏主意(http://stackoverflow.com/questions/6006860/why-should-one-not -derive-从-C-STD-字符串类)。私有继承*可能被认为是足够安全的,尽管它仍然在你的类和'std :: string'之间建立了紧密的耦合。看到一个有趣的讨论[在这里滥用继承](http://www.gotw.ca/publications/mill06.htm)。至于错误,请张贴一个简短的,自包含的例子来重现问题。 – juanchopanza

+1

你不是从std :: string(或map,vector,或任何其他容器)派生的。在我遇到这种情况的所有情况下,都有几种更好的解决方案。 无论何时您需要从stl容器派生,都应考虑封装,意思是将容器用作类的成员,或者使用私有继承。 – Peter

回答

5

在C++中任何声明都可以将解析为一个函数声明,比如&hellip;

spstring byteaddstr(std::string(argv[4])); //convertchar* to spstring 

解析为函数声明。

I.e.不是一个变量。

在这种特殊情况下的一种解决方案,是添加额外的括号:

spstring byteaddstr((std::string(argv[4]))); //convertchar* to spstring 

这就是所谓的最棘手的解析在C++中,虽然有些人不同意是否斯科特迈尔斯原来使用的是这个术语通常与现在使用的一样。


顺便说一下,一个一般应该有一个很好的理由获得std::string,因为它增加了复杂性和混乱(你可以放心地忽略有关动态分配的担忧,因为代码,可动态分配std::string值得无论它得到什么)。所以,我建议你不要这样做。

+0

是的,这是buttom线。非常感谢! – Popopo

+0

那么,如果我们忽视对动态分配的担心,那么究竟是什么问题的继承?我的理解是,继承使代码更复杂,更难理解。还有更多吗? –

+0

@BЈовић:不是真的,imo。但这些属性转化为*更多的工作*。 –

0

继承std::string(和STL容器)是一个坏主意。它们不是为了作为基类而设计的。

重要的是,它们不一定具有虚拟析构函数,因此可以使派生类的内存管理变得困难。

你也会失去可读性:如果我看到一个STL类或函数,那么我就知道到底会发生什么,因为它假定我已经记住了标准。对于派生类,我必须依赖其文档或程序评论。

所以我的回答:没有正确的方式从std :: string继承。