классы c ++ - как передать функцию включенному классу для ее использования? - PullRequest
2 голосов
/ 02 августа 2011

Я уверен, что это как-то связано с виртуальными функциями, но я изо всех сил пытаюсь понять, как.

Вот моя (упрощенная) ситуация:

Грубо говоря, программа имеет одну пару файлов (computer.h), рисующую компьютер с пустым экраном, и другую пару (program.h), функцию которой нужно рисовать на экране этого компьютера

Компьютерный класс будет использоваться повторно во многих различных ситуациях, поэтому функцию рисования экрана необходимо передать в общем виде

in computer.h:

include "screen.h"

class computer {

    void drawComputer(); //this function draws a picture of a computer
    void drawMonitor();

};

in computer.cpp:

void computer::drawComputer(){

    //draws all the components then the monitor

    drawMonitor(); //this is where the external function (from class screen) needs to execute
}

void computer::drawMonitor(){
    //draws the background and border of screen
}

в program.h:

class program {

    //many other program functions

    void drawScreen();

};

in program.cpp:

//many other program functions

void program::drawScreen(){
    //this function draws the contents of the screen
}

Мой вопрос, с program.cpp, как мне «отправить» функцию drawScreen() для выполнения в функции drawMonitor() в computer.cpp?

Редактировать

@ Крис кажется почти таким же, как я, но когда я пытаюсь его реализовать, я получаю следующие ошибки:

testApp.h:40: error: 'testApp::prog' cannot appear in a constant-expression
testApp.h:40: error: `&' cannot appear in a constant-expression
testApp.h:40: error: a cast to a type other than an integral or enumeration type cannot appear in a constant-expression
testApp.h:40: error: ISO C++ forbids initialization of member 'isprog'
testApp.h:40: error: making 'isprog' static
testApp.h:40: error: invalid in-class initialization of static data member of non-integral type 'IScreen*'
testApp.h:41: error: 'isprog' has not been declared
testApp.h:42: error: ISO C++ forbids declaration of 'comp1' with no type
testApp.h:42: error: expected ';' before '.' token

Строки

39    Program prog;
40    IScreen *isprog = dynamic_cast<IScreen*>(&prog);
41    OP1 comp1(isprog);
42    comp1.drawScreen();

Кто-нибудь знает, где я ошибаюсь с реализацией?

Ответы [ 3 ]

3 голосов
/ 02 августа 2011

Ну, ты на полпути.Для чего-то вроде этого, да, я бы использовал виртуальные функции (для определения абстрактного интерфейса).Вот основная схема того, как я это сделаю:

// First create a class to define an interface for drawing a screen
class IScreen
{
public:
    // Defines an interface named drawScreen
    virtual void drawScreen() = 0;
};

// Next actually implement the interface
class Program : public IScreen
{
public:
    // Here we actually implement it
    virtual void drawScreen()
    {
        // Draw some stuff here
    }
};

// You can implement this more than once if you want
class BlueScreenOfDeathScreen : public IScreen
{
public:
    virtual void drawScreen()
    {
        // Draw a BSOD on the screen
    }
};

// Finally, use the interface
class Computer
{
private:
    IScreen* myScreen;

public:
    Computer(IScreen* screen)
        : myScreen(screen)
    {
    }

    void drawComputer()
    {
        // ...
    }

    void drawMonitor()
    {
        // Draw the monitor
        // ...

        // Draw the screen
        myScreen->drawScreen();
    }
};

Делая это таким образом, вы можете легко определить несколько реализаций IScreen и быстро поменять их с минимальными изменениями в вашем коде.

// Render using the "Program" class
Program prog;
IScreen *iprog = dynamic_cast<IScreen*>(&prog);
Computer comp1(iprog);
comp1.drawScreen();

// Render using the "BlueScreenOfDeathScreen" class
BlueScreenOfDeathScreen bsod;
IScreen *ibsod = dynamic_cast<IScreen*>(&bsod);
Computer comp2(ibsod);
comp2.drawScreen();

Легко, нет?

1 голос
/ 02 августа 2011

Вам нужно создать экземпляр program в своем классе компьютера, например:

Program mypgm;

и затем в вашем

void computer::drawMonitor(){
    //draws the background and border of screen
   mypgm.DrawScreen();

}
0 голосов
/ 02 августа 2011

Самый простой ответ - иметь объект program внутри computer и вызывать drawScreen() изнутри. т.е.

class computer {
  program prg;  // <--- internal object
//...
};
void computer::drawMonitor() {
  prg.drawScreen();
}

Другой способ - передать эталонный объект program в drawMonitor и вызвать метод. т.е.

void computer::drawMonitor(program &prg) {  // <--- pass by reference
  prg.drawScreen();
}
...