【问题标题】:What is the way to inherit std::string right?继承 std::string 的方法是什么?
【发布时间】:2013-12-29 00:53:18
【问题描述】:

最近,我一直想定义一个std::string的子类spstring。它在 spstr.h 中声明:

#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的一个实例,为什么不能调用它的成员函数呢?

【问题讨论】:

  • 您通常不希望从 STL 容器派生。
  • 一般来说,从std::string继承被认为是个坏主意,尤其是公开(see related SO post)。私有继承可能被认为足够安全,尽管它仍然在您的类和std::string 之间强加了紧密耦合。请参阅abuses of inheritance here 上的有趣讨论。至于错误,请发布一个简短的、独立的示例来重现该问题。
  • 您不是从 std::string (或地图、向量或任何其他容器)派生的。在我遇到这种情况的所有情况下,都有几种更好的解决方案可用。每当您需要从 stl 容器派生时,请考虑封装,这意味着要么将容器用作类的成员,要么使用私有继承。
  • 请注意,按值传递 std::string 效率低下,请改用 const 引用或移动语法。
  • 关于使用 STL 容器定义新类型,组合是比继承最好的方法。见这里:stackoverflow.com/questions/14089088/…

标签: c++ string class inheritance


【解决方案1】:

在 C++ 中,任何 可以 被解析为函数声明的声明,例如……

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

解析为函数声明。

即不是变量。

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

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

这在 C++ 中被称为最令人头疼的解析,尽管有些人不同意 Scott Meyers 最初对该术语的使用是否与现在使用的一样普遍。


顺便说一句,从std::string派生通常应该有一个很好的理由,因为它增加了复杂性和混乱(你可以放心地忽略对动态分配的担忧,因为动态分配的代码分配std::string 应得的一切)。所以,我建议你不要这样做。

【讨论】:

  • 是的,这是底线。非常感谢!
  • 那么,如果我们忽略对动态分配的关注,那么继承到底有什么问题呢?我的理解是继承使代码更复杂,更难理解。还有更多吗?
  • @BЈовић:不是真的,imo。但这些属性转化为更多工作
【解决方案2】:

std::string(和 STL 容器)继承是个坏主意。它们并非设计为作为基类运行。

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

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

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

【讨论】:

    猜你喜欢
    • 2010-11-27
    • 1970-01-01
    • 1970-01-01
    • 2014-01-31
    • 2023-04-09
    • 1970-01-01
    • 2011-12-30
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多