在 C++ 中扩展内置类

Posted

技术标签:

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

我知道已被弃用,但出于某些原因我仍然想这样做。

我想将我的自定义方法添加到从 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 析构函数。这意味着你不能多态地使用它们。 私有继承与组合基本相同,所以就用组合吧。如果您觉得需要从标准容器继承,那么您应该将其视为您的设计存在缺陷的标志。 关于坏习惯,习惯(好坏)往往会坚持下去。所以最好开始在任何地方都养成良好的习惯并坚持下去? 【参考方案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“技术术语是,“糟糕”。”;)

以上是关于在 C++ 中扩展内置类的主要内容,如果未能解决你的问题,请参考以下文章

Python继承扩展内置类

c++(非内置/类)静态成员

Django扩展内置User类

Loopback - 扩展内置模型的最简单方法

扩展Django内置的auth模块代码示例

C++ 中的三种类型