-1

I know extending built-in classes in C++ is deprecated, but still I want to do it for some reasons.

I wanna add my custom methods to a class (str) that extends/inherits from the std::string class (this is for an example)

But when I do so there's some problem I am facing with the methods that are already there in the std::string class (built-in methods), for example,

#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"
}

How do I get around this?

  • 1
    You are mixing composition and inheritance. Choose one. For inheritance, you should get rid of `string s;` member. – Yksisarvinen Sep 06 '21 at 14:17
  • @Yksisarvinen can u explain with respect to inheritance? – Master Coder xD Sep 06 '21 at 14:18
  • 1
    Note that few of the standard classes are designed to be publicly inherited, as they don't have `virtual` destructors. That means you can't use them polymorphically. – Some programmer dude Sep 06 '21 at 14:20
  • Also please read [Why should I not #include ?](https://stackoverflow.com/questions/31816095/why-should-i-not-include-bits-stdc-h) and [Why is "using namespace std;" considered bad practice?](https://stackoverflow.com/questions/1452721/why-is-using-namespace-std-considered-bad-practice) – Some programmer dude Sep 06 '21 at 14:20
  • @Someprogrammerdude r u saying I shouldn't inherit or I should inherit it in private mode? – Master Coder xD Sep 06 '21 at 14:21
  • @Someprogrammerdude I am using `#include ` and `using namespace std;` for a simplified example lol – Master Coder xD Sep 06 '21 at 14:22
  • 1
    Private inheritance is basically the same as composition, so go with composition. If you ever feel the need to inherit from a standard container then you should take that as a sign that your design is flawed. – Some programmer dude Sep 06 '21 at 14:22
  • Few of the standard classes are designed to be used polymorphically. Even if you use your custom class heavily, it still won't be really usable by external code. That's the general reason this is avoided, not the FUD you may hear otherwise. – StoryTeller - Unslander Monica Sep 06 '21 at 14:22
  • 2
    Regarding the bad habits, habits (good *and* bad) tend to stick. So better start using good habits everywhere and have those stick? – Some programmer dude Sep 06 '21 at 14:23
  • So how do I get around this problem? If I can do it using composition, can y'all explain how? – Master Coder xD Sep 06 '21 at 14:23
  • I mean @Someprogrammerdude can u post an answer with code? – Master Coder xD Sep 06 '21 at 14:27
  • It is not deprecated. It was always known not to work. – n. m. could be an AI Sep 06 '21 at 14:33
  • `std::string` is the prime example of a class with a too crowded interface. Instead of adding more, prefer free functions over member functions when possible. You wont be able to access anything that isnt accessible in a free function, because `std::string` has zero `protected` members – 463035818_is_not_an_ai Sep 06 '21 at 14:42

1 Answers1

5

std::string doesn't know about your string s; member. It cannot possibly use it in its methods. If you want to use inheritance over composition, you need to use whatever is available under public interface of std::string - in this case, its constructors.

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
};

As a footnote, there is nothing deprecated about inheriting from standard containers, but they are not meant for that and you can only do a very limited set of things safely. For example, this is Undefined Behaviour:

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

More detailed explanation in this question.

Also, you should strongly avoid <bits/stdc++.h> and using namespace std; and in particular you should not mix them. You will strip yourself of almost every name and it produces hard to find bugs.

Yksisarvinen
  • 18,008
  • 2
  • 24
  • 52
  • Can u give a solution with respect to composition too? – Master Coder xD Sep 06 '21 at 14:29
  • @MasterCoderxD For composition you start with `string s;` member as you had and write methods in your own class that will call methods on that member. E.g. `str::size(){return s.size();}`. Note that `std::basic_string` has over a hundered of methods, so if you want to replicate its behaviour to the letter, it will be not feasible. – Yksisarvinen Sep 06 '21 at 14:32
  • Where in the linked question is the part about the code snippet being UB? I can see problems if the sub class needed a destructor of its own, but since it doesn't I don't understand where the UB comes from. – Voo Sep 06 '21 at 14:32
  • Alr Imma use inheritance, ty bruv – Master Coder xD Sep 06 '21 at 14:33
  • @Voo the accepted answer links to here: https://isocpp.org/wiki/faq/virtual-functions#virtual-dtors "The technical term for that is, “Yuck.”" ;) – 463035818_is_not_an_ai Sep 06 '21 at 14:36
  • @Voo It seems it's not described directly in the answer, but in the link in that answer. UB happens when you delete object through base class pointer, when that base class does not have a `virtual` destructor and that's just the letter of standard. It will probably not break with trivial destructor, although I'm not sure what happens if there was e.g. an `std::unique_ptr` as a member. – Yksisarvinen Sep 06 '21 at 14:37
  • The built-in methods of `std::string` don't modify the members of `str` why? – Master Coder xD Sep 06 '21 at 16:12
  • @MasterCoderxD What do you mean? If you have class `Base`, which has some methods, and class `Child`, which inherits from `Base`, then `Base` cannot possibly know about `Child` and its members, and it cannot use those members. `Base` only knows about `Base` and its own members. `Child` knows about `Base` members and `Child` members and it can use both. – Yksisarvinen Sep 07 '21 at 07:40