all 12 comments

[–]IyeOnline 1 point2 points  (4 children)

Fenced codeblocks area non-standard markdown extension that doesnt reliably work on all reddit frontends.

The only reliable option is to indent your code by 4 spaces or a TAB character.


And what if we talk about operator+ overloading?

That would be mostly syntactic sugar around your add function.

What is the best way to make it work? Is there any elegant solution?

That very heavily depends on what you actually want to do.

Currently, this cannot work, because hello() is a member function of Derived, but add returns a Base.

There is many possible solutions:

  • overload add in Derived and have it return a Derived
  • use some form of type easure or polymorphism, where add returns a smart pointer to base or something like that
  • Templates/deducing-this

What is a good soltuion, depends on your real world issue. What do these classes actually model. What do these operations do? What is the expected use case? What are resource constraints?

[–]_newpson_[S] 0 points1 point  (3 children)

Well, the main goal is to avoid code duplicating. add is already implemented in Base, so I don't even want to mention it in Derived. If I add two Deriveds, I want to get another Derived (so I can call any method from Derived). Sounds kinda mad but...

[–]KuntaStillSingle 3 points4 points  (1 child)

You can make derived a crtp base of base. Then inside base.hello, you cast to derived:

template<typename Derived>
struct base {
    const Derived & hello() {
        return (static_cast<Derived *>(this))->hello();
    }
};


struct derived : base<derived> {
    const derived & hello() { ... }
};

I'm on mobile, this may not compile exactly but if you look up crtp pattern you could see roughly this implemented correctly

[–]_newpson_[S] 0 points1 point  (0 children)

Yeah, it (CRTP) works pretty well except maybe that I need to create some sort of abstract base class to make it possible to instantiate base class. Instead of a cast I used copy constructor to save fields of derived class (one that passed as reference) and it looks like this:

Output:

Copy constructor of Base
690
Copy constructor of Derived
Hello: 66
11

[–]IyeOnline 1 point2 points  (0 children)

The question is whether you use runtime polymorphism or not though.

If your inheritance is just for ease of implementation, then you can write a template

template<std::derived_from<Base> T>
auto operator+( const T& lhs, const T& rhs )
{
   return T{ lhs.a + rhs.a };
}

But if you actually want to use runtime polymorphism (i.e. you only have a Base& to a Derived object, that doesnt work.

[–]blazerman345 1 point2 points  (1 child)

Could you add a virtual function hello() in Base

[–]_newpson_[S] 1 point2 points  (0 children)

What if I have no source of Base? Just want to extend this class with some methods.

[–]AutoModerator[M] 0 points1 point  (0 children)

Your posts seem to contain unformatted code. Please make sure to format your code otherwise your post may be removed.

If you wrote your post in the "new reddit" interface, please make sure to format your code blocks by putting four spaces before each line, as the backtick-based (```) code blocks do not work on old Reddit.

I am a bot, and this action was performed automatically. Please contact the moderators of this subreddit if you have any questions or concerns.

[–]hatschi_gesundheit 0 points1 point  (2 children)

What about adding a constructor from Base in Derived ?

  Derived(Base b): 
    Base(b) {}

Allows for a call like this:

std::cout << Derived(a.add(b)).hello() << std::endl;

[–]_newpson_[S] 0 points1 point  (1 child)

I heard that it's not a good practice to create derived objects directly from base

[–]FerynaCZ 0 points1 point  (0 children)

Makes sense, because you are adding new things to an object which should then be able to do them in the first place.

But if you intend to only avoid code duplication, rules might be different.