【问题标题】:Extending built-in classes in C++在 C++ 中扩展内置类
【发布时间】:2021-09-06 14:15:51
【问题描述】:

我知道在 C++ 中扩展内置类已被弃用,但出于某些原因我仍然想这样做。

我想将我的自定义方法添加到从 std::string 类扩展/继承的类 (str)(这是一个示例)

但是当我这样做时,我会遇到一些问题,例如 std::string 类中已经存在的方法(内置方法),

#include <bits/stdc++.h>
using namespace std;
class str : public string {
  public:
    string s;
    str(string s1) {
      s = s1; //ig the problem is here
    }
};
int main() {
  str s("hello world");
  cout << s.size(); //prints out 0 not 11 => length of "hello world"
}

我该如何解决这个问题?

【问题讨论】:

  • 您正在混合组合和继承。选一个。对于继承,你应该去掉 string s; 成员。
  • @Yksisarvinen 你能解释一下继承吗?
  • 请注意,很少有标准类被设计为公开继承,因为它们没有virtual 析构函数。这意味着你不能多态地使用它们。
  • 私有继承与组合基本相同,所以就用组合吧。如果您觉得需要从标准容器继承,那么您应该将其视为您的设计存在缺陷的标志。
  • 关于坏习惯,习惯(好坏)往往会坚持下去。所以最好开始在任何地方都养成良好的习惯并坚持下去?

标签: c++ class oop


【解决方案1】:

std::string 不知道您的string s; 成员。它不可能在其方法中使用它。如果你想使用继承而不是组合,你需要使用std::string的公共接口下可用的任何东西——在这种情况下,是它的构造函数。

class str : public string {
  public:
    str(string s1): string(s1) //initialize base class using its constructor
    {
    }
};

// or

class str : public string {
  public:
    using string::string; //bring all std::string constructors into your class
};

作为脚注,从标准容器继承并没有被弃用,但它们并不是为此而生的,您只能安全地做非常有限的一组事情。例如,这是未定义的行为:

std::string* s = new str("asdf");
delete s; // UB!

更详细的解释见this question

此外,您应该强烈避免使用&lt;bits/stdc++.h&gt;using namespace std;,尤其是不要混合使用它们。你会剥夺自己几乎所有的名字,这会产生很难找到的错误。

【讨论】:

  • 你能给出一个关于构图的解决方案吗?
  • @MasterCoderxD 对于组合,您从 string s; 成员开始,并在您自己的类中编写将调用该成员方法的方法。例如。 str::size(){return s.size();}。请注意,std::basic_string 有上百种方法,因此如果您想将其行为复制到字母上,那将是不可行的。
  • 链接问题中关于代码 sn-p 是 UB 的部分在哪里?如果子类需要自己的析构函数,我可以看到问题,但因为它不需要我不明白 UB 来自哪里。
  • Alr Imma 使用继承,ty bruv
  • @Voo 接受的答案链接到此处:isocpp.org/wiki/faq/virtual-functions#virtual-dtors“技术术语是,“糟糕”。”;)
猜你喜欢
  • 2010-09-26
  • 1970-01-01
  • 1970-01-01
  • 2011-06-22
  • 1970-01-01
  • 2013-08-26
  • 2011-07-20
  • 2010-12-13
  • 2018-10-06
相关资源
最近更新 更多