Bharat Pawar
Bharat Pawar

Reputation: 3

How do I call method using interface pointer which is part of its concrete class and not part of interface

I have an interface Test_I, which is implemented by many classes like myTest1,myTest2. I have new requirement of a writing a new class myTest3 which has to be subclass of interface Test_I. Along with existing methods myTest3 has some other new methods like mySomeOtherTestFunction which has no relation with parent interface Test_I. I must call all methods of concrete classes using interface pointer only and this can not be changed. How can I solve this problem without adding this method into parent interface.

class Test_I
{
public :
    virtual void myTestFunction1() = 0;

    virtual void myTestFunction2() = 0;
};


class myTest1 : public Test_I
{

public : 

    virtual void myTestFunction1()
    {
        cout<<"in myTest1::mytestFunction1"<<endl;
    }

    virtual void myTestFunction2()
    {
        cout<<"in myTest1::mytestFunction2"<<endl;
    }

};


class myTest2 : public Test_I
{

public : 

    virtual void myTestFunction1()
    {
        cout<<"in myTest2::myTestFunction1"<<endl;
    }

    virtual void myTestFunction2()
    {
        cout<<"in myTest2::myTestFunction2"<<endl;
    }
};


class myTest3 : public Test_I
{
public : 
    virtual void myTestFunction1()
    {
        cout<<"in myTest3::myTestFunction1"<<endl;
    }

    virtual void myTestFunction2()
    {
        cout<<"in myTest3::myTestFunction2"<<endl;
    }

    //I need one more method here, which is specific to myTest3 class and not related to interface Test_I
    virtual void mySomeOtherTestFunction()
    {
        cout<<"in myTest3::mySomeOtherTestFunction"<<endl;
    }
};


int _tmain(int argc, _TCHAR* argv[])
{

    myTest1 t1;
    myTest2 t2;
    myTest3 t3;

    Test_I *pTest = &t1;    
    pTest->myTestFunction1();
    pTest->myTestFunction2();

    pTest = &t2;
    pTest->myTestFunction1();
    pTest->myTestFunction2();

    pTest = &t3;
    pTest->myTestFunction1();
    pTest->myTestFunction2();
    pTest->mySomeOtherTestFunction(); //This will fail with error : 'mySomeOtherTestFunction' : is not a member of 'Test_I'

    return 0;
}

Upvotes: 0

Views: 497

Answers (1)

Thomas Sablik
Thomas Sablik

Reputation: 16446

You have to downcast the pointer:

#include <iostream>
using std::cout;

class Test_I
{
public :
    virtual void myTestFunction1() = 0;

    virtual void myTestFunction2() = 0;
};


class myTest1 : public Test_I
{

public : 

    void myTestFunction1() override
    {
        cout<<"in myTest1::mytestFunction1\n";
    }

    void myTestFunction2() override
    {
        cout<<"in myTest1::mytestFunction2\n";
    }

};


class myTest2 : public Test_I
{

public : 

    void myTestFunction1() override
    {
        cout<<"in myTest2::myTestFunction1\n";
    }

    void myTestFunction2() override
    {
        cout<<"in myTest2::myTestFunction2\n";
    }
};


class myTest3 : public Test_I
{
public : 
    void myTestFunction1() override
    {
        cout<<"in myTest3::myTestFunction1\n";
    }

    void myTestFunction2() override
    {
        cout<<"in myTest3::myTestFunction2\n";
    }

    virtual void mySomeOtherTestFunction()
    {
        cout<<"in myTest3::mySomeOtherTestFunction\n";
    }
};


int main()
{

    myTest1 t1;
    myTest2 t2;
    myTest3 t3;

    Test_I *pTest = &t1;    
    pTest->myTestFunction1();
    pTest->myTestFunction2();

    pTest = &t2;
    pTest->myTestFunction1();
    pTest->myTestFunction2();

    pTest = &t3;
    pTest->myTestFunction1();
    pTest->myTestFunction2();

    // if cast fails, returns nullptr
    myTest3 *newPTest = dynamic_cast<myTest3 *>(pTest);
    if (newPTest != nullptr) {
        newPTest->mySomeOtherTestFunction();
    }

    // cast without check, undefined behavior if Test_I is not a base class of myTest3
    static_cast<myTest3 *>(pTest)->mySomeOtherTestFunction();

    return 0;
}

Use dynamic_cast if you want to use runtime type information (RTTI) to check if the cast is possible or static_cast if you are sure that this cast is possible.

Upvotes: 2

Related Questions