Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Call Virtual Function for Specific Class on Object in C++

Tags:

c++

I need to call a function from "declaration" type on some object from outside the class. I did a small code sample and put as comments the desired behavior as I don't know exactly how to ask this:)

template<typename T>
void hun(T* obj, class C* c)
{
    //do some checking on c
    if(some conditions from c are true)
    {
        //call fun from T ignoring it's virtual
    }
}

struct A
{
    virtual void fun(){};
    virtual void gun(class C* c)
    {
        //do something specific to A
        hun(this, c); //here call fun from A even if real type of this is B
    };
}

struct B : public A
{
    void fun(){};
    void gun(class C* c)
    {
        //do something specific to B
        hun(this, c);//here call fun from B even if real type of this is something derived from B
    };
}

Is it possible to achieve this behavior?

I know I can call fun() from inside the class using A::fun() or B::fun(), but the checking from hun() is common for all classes and I don't want to pollute gun() with this code.

like image 978
Mircea Ispas Avatar asked Apr 27 '13 14:04

Mircea Ispas


1 Answers

(This has probably been already answered somewhere else..)

You can explicitly call one override of a virtual function using a qualified-id. A qualified-id for a member function is of the form my_class::my_function.

For reference, see C++ Standard [expr.call]/1:

If the selected function is non-virtual, or if the id-expression in the class member access expression is a qualified-id, that function is called. Otherwise, its final overrider (10.3) in the dynamic type of the object expression is called.

Example

template<typename T>
void hun(T* obj, class C* c)
{
    //do some checking on c
    if(some conditions from c are true)
    {
        //call fun from T ignoring it's virtual
        obj->T::fun(); // T::fun is a qualified-id
    }
}

struct A
{
    virtual void fun(){};
    virtual void gun(class C* c)
    {
        //do something specific to A
        hun(this, c); //here call fun from A even if real type of this is B
    };
}; // note: semicolon was missing

struct B : public A
{
    void fun(){};
    void gun(class C* c)
    {
        //do something specific to B
        hun(this, c);//here call fun from B even if real type of this is something derived from B
    };
};
like image 178
dyp Avatar answered Oct 28 '22 17:10

dyp