0

this is basic C++ but I am getting to a point where python actually seems way simpler. Suppose:

class Base
{
public: 
    virtual ~Base() = default;
    virtual std::string type() const { return "base"; }; 
};

class Derived1 : public Base
{
public:
    virtual std::string type() const { return "dervied1"; }; 
};

class Derived2 : public Base
{
public:
    virtual std::string type() const { return "dervied2"; }; 
};

I find my self having other functions of type:

void process(Base& derived_from_base)
{
};

Q1: How do I know what I am taking as input, should I call type() and later down cast, problem is I think type() will give always "base"?

Q2: This is so annoying. I later have to down case the input to the correct derived class. I am just wondering if python is doing this in the background, am I sure that with all of this I am faster than python?

Q3: Is it true I can replace virtual function/inheritance and all casting using templates? (heard this somewhere and not sure).

Thank you very much.

Vero
  • 313
  • 2
  • 9
  • C++ *is* quite verbose. And for some things C++ might be a better solution. for other things Python might be a better solution. And for yet other things maybe some other language completely. All Turing-complete languages can be used to solve just about any problem, but some languages tend to fit certain problems better than others. That's the reason it's always good to know multiple languages (of different categories). And to have a good set or initial requirements that an appropriate language can be selected together with the design being written. – Some programmer dude Apr 15 '22 at 18:21
  • Thank you! I know multiple languages, I made my decision to go with C++ because I am using some complex libraries only available in C++. Thanks again, but this does not answer my questions :) ? – Vero Apr 15 '22 at 18:24

1 Answers1

0

Q1: How do I know what I am taking as input?

A1: Keep the full type instead of erasing it to the base class. E.g. instead of

void process(Base& base) {
    if (base.type() == "derived1") process_derived1(static_cast<Derived1&>(base));
    else process_anything_else(base);
}

int main() {
    std::unique_ptr<Base> base = std::make_unique<Derived1>();
    process(*base);
}

use

void process(Derived1& derived1) { process_derived1(derived1); }
void process(auto& t) { process_anything_else(t); }

int main() {
    Derived derived1;
    process(derived1);
}

Q2: I am just wondering if python is doing this in the background, am I sure that with all of this I am faster than python?

A2: Python has something like this:

int main() {
    Object derived1; // a hash map
    derived1["__type__"] = "Derived1";
}

With the approach from A1, you are faster than anything (assuming everything else in the program isn't worse) because of static dispatch: thanks to templates, overload resolution happens at compile time and therefore costs nothing.

Q3: Is it true I can replace virtual function/inheritance and all casting using templates? (heard this somewhere and not sure)

A3: With proper design, you can do that most of the times, e.g. see A1. However, some things force linking dynamically: OS API, game plugins etc. In such cases, consider localizing the clumsy borderline part, so most of the code can be written as usual.

virtual function/inheritance

Note: inheritance without virtual functions is perfectly fine and zero-cost (on its own), e.g. see CRTP.

passing_through
  • 1,778
  • 12
  • 24
  • thanks very much, with all respect this of course solves the problem but I still don't like it :) I need something perfect. I hope there is other options.. – Vero Apr 16 '22 at 16:45