Как вызвать метод, используя указатель интерфейса, который является частью его конкретного класса, а не частью интерфейса - PullRequest
0 голосов
/ 14 января 2020

У меня есть интерфейс Test_I, который реализован многими классами, такими как myTest1, myTest2. У меня есть новое требование написания нового класса myTest3, который должен быть подклассом интерфейса Test_I. Наряду с существующими методами myTest3 имеет некоторые другие новые методы, такие как mySomeOtherTestFunction, который не имеет отношения к родительскому интерфейсу Test_I. Я должен вызывать все методы конкретных классов, используя только указатель интерфейса, и это нельзя изменить. Как я могу решить эту проблему, не добавляя этот метод в родительский интерфейс.

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;
}

1 Ответ

2 голосов
/ 14 января 2020

Вы должны уменьшить указатель:

#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;
}

Используйте dynamic_cast, если хотите использовать информацию о типе времени выполнения (RTTI), чтобы проверить, возможно ли приведение, или static_cast, если вы уверены, что этот актерский состав возможен.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...