0

I have some code which seems similair to this:

#include <iostream>

class Base {
public:
    void test() {
        std::cout << "Base::test()" << std::endl; 
    }

    void test2() {
        test();
    }
};

class Derived : public Base {
public:
    void test() {
        std::cout << "Derived::test()" << std::endl;
    }
};

int main() {
    Derived d;
    d.test2();
    return 0;
}

Now this outputs ofcourse Base::test(), however I want it to output Derived::test() without making use of virtual function calls and using an different notation for the function overload called: Derived::test.

Does someone know if this is possible to achieve?

svick
  • 236,525
  • 50
  • 385
  • 514
Tim
  • 5,521
  • 8
  • 36
  • 69
  • If I understand u corrent u want d.test2() to invoke directly d.test(), right ? According to my knowledge there is no way to do that without virtual functions. Their purpose is for exactly this cases. – Kamen Stoykov Jun 26 '13 at 16:10
  • Yes, without overloading `Base::test2()`, without using an different notation for `Derived` and also without losing performance (e.g. virtual function calls). – Tim Jun 26 '13 at 16:12
  • Are you allowed to modify `Base`? – Andy Prowl Jun 26 '13 at 16:14
  • @AndyProwl Yes, completely, but it may not effect `Derived` by for example inheriting unnecessary members. – Tim Jun 26 '13 at 16:15
  • You may try member function pointers. Then you can invoke d.test2(d.test); and from test2() to invoke right function according to pointer. – Kamen Stoykov Jun 26 '13 at 16:16
  • 1
    @Tim Have you actually verified that the virtual function call measurably affects performance here? – svick Jun 26 '13 at 16:27
  • @Roddy Some derived classes are already implemented, so no it might be even more postmature optimization. – Tim Jun 26 '13 at 16:27
  • @svick No, I figured, because the function will be called a lot of times. – Tim Jun 26 '13 at 16:28
  • 1
    @Tim That's exactly what is meant by “premature optimization”. Quite often, where you think a bottleneck might be is not where it actually will be. If you're worried about performance, first write your code without optimizations, then measure it, then optimize the parts that are actually slowing you down. – svick Jun 26 '13 at 16:30
  • @svick, Roddy Forgive me for trying to optimize my C++ code premature. I'm pretty convinced that it's important to not lose any performance in my case. You can't possibly disagree with me without knowing what I'm writing, which is also unrelevant for this question. So if you know a solution, please provide me one, if not, you're not helping me by telling me it's not important. – Tim Jun 26 '13 at 16:45

1 Answers1

3

You could use the so-called Curiously Recurring Type Pattern (CRTP) and make Base a class template:

template<typename D>
class Base {
public:
    void test() {
        std::cout << "Base::test()" << std::endl;
    }

    void test2() {
        (static_cast<D*>(this))->test();
    }
};

Then, you would derive Derived from Base<Derived> instead of just Base:

class Derived : public Base<Derived> {
//                     ^^^^^^^^^^^^^
//                     This is the only change required in Derived
public:
    void test() {
        std::cout << "Derived::test()" << std::endl;
    }
};

Here is a live example.

Andy Prowl
  • 124,023
  • 23
  • 387
  • 451
  • Then he has to check which one is faster - casting or virtual function calls. – Kamen Stoykov Jun 26 '13 at 16:18
  • @KamenStoykov The cast could be done in the constructor. @AndyProwl It is a nice solution, but I don't think I have the luxery to change the inheritance type of `Base` to a template class `Base`. Some derived classes are already implemented. – Tim Jun 26 '13 at 16:20
  • @Tim: I see. Then I really don't believe there is any other way than using virtual functions. – Andy Prowl Jun 26 '13 at 16:22
  • @AndyProwl Thanks though. Storing the virtual function wouldn't cause any performance loss, right? – Tim Jun 26 '13 at 16:24
  • @Tim: What do you mean by "storing the virtual function"? – Andy Prowl Jun 26 '13 at 16:25
  • @AndyProwl Storing it in a function pointer. I'm no C expert, so that's why the question. – Tim Jun 26 '13 at 16:26