【问题标题】:How to segment this code into headers and source files and classes?如何将此代码分段为头文件和源文件和类?
【发布时间】:2016-01-03 22:25:20
【问题描述】:

我正在尝试学习 c++ 和 sdl,但到目前为止我失败得很惨。我一直在关注 Lazy Foo 关于 sdl 的教程,但在他的所有教程中,代码都被转储到一个大的主源文件中。我正在寻找一种方法将这一大块代码分割并划分为头文件和类,以便我的 main.cpp 文件将只有一个 int main 函数,而所有其他 init 和 exit 函数将保留在其他文件中。我不知道这是否是一种好习惯,但到目前为止,我已经读到您应该将代码分成几部分,以便它运行得更快、更流畅。如果你能给我看一些例子,我相信我能弄清楚其余的。这是我的代码以及我尝试对其进行分区的方式:



main.cpp

#include <SDL.h>
#include <stdio.h>

#include "game_state.h"
#include "game_state.cpp"

int main( int argc, char* args[] ) {

    if( !init() )
    {
        printf( "Failed to initialize!\n" );
    } else {
        //Load media
        if( !loadMedia() )
        {
            printf( "Failed to load media!\n" );
        } else {
            //Apply the image
            SDL_BlitSurface( gHelloWorld, NULL, gScreenSurface, NULL );

            //Update the surface
            SDL_UpdateWindowSurface( gWindow );

            //Wait two seconds
            SDL_Delay( 2000 );
        }
    }

    //Free resources and close SDL
    onExit();

    return 0;

}

game_state.h

#ifndef PLAYER_H
#define PLAYER_H

#include <SDL.h>
#include <stdio.h>

//The window we'll be rendering to
SDL_Window *gWindow;

//The surface contained by the window
SDL_Surface *gScreenSurface;

//The image we will load and show on the screen
SDL_Surface *gHelloWorld;

bool init();

bool loadMedia();

void onExit();

#endif

game_state.cpp

#include "game_state.h"


//Screen dimension constants
const int SCREEN_WIDTH = 640;
const int SCREEN_HEIGHT = 480;




bool init() {
    //Initialization flag
    bool success = true;

    //Initialize SDL
    if( SDL_Init( SDL_INIT_VIDEO ) < 0 )
    {
        printf( "SDL could not initialize! SDL_Error: %s\n", SDL_GetError() );
        success = false;
    }
    else
    {
        //Create window
        gWindow = SDL_CreateWindow( "SDL Tutorial", SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, SCREEN_WIDTH, SCREEN_HEIGHT, SDL_WINDOW_SHOWN );
        if( gWindow == NULL )
        {
            printf( "Window could not be created! SDL_Error: %s\n", SDL_GetError() );
            success = false;
        }
        else
        {
            //Get window surface
            gScreenSurface = SDL_GetWindowSurface( gWindow );
        }
    }

    return success;
}

bool loadMedia() {
    //Loading success flag
    bool success = true;

    //Load splash image
    gHelloWorld = SDL_LoadBMP( "02_getting_an_image_on_the_screen/hello_world.bmp" );
    if( gHelloWorld == NULL )
    {
        printf( "Unable to load image %s! SDL Error: %s\n", "02_getting_an_image_on_the_screen/hello_world.bmp", SDL_GetError() );
        success = false;
    }

    return success;
}

void onExit()
{
    //Deallocate surface
    SDL_FreeSurface( gHelloWorld );
    gHelloWorld = NULL;

    //Destroy window
    SDL_DestroyWindow( gWindow );
    gWindow = NULL;

    //Quit SDL subsystems
    SDL_Quit();
}

lazy foo 的原始 main.cpp,我尝试对其进行分段:

//Using SDL and standard IO
#include <SDL.h>
#include <stdio.h>

//Screen dimension constants
const int SCREEN_WIDTH = 640;
const int SCREEN_HEIGHT = 480;

//Starts up SDL and creates window
bool init();

//Loads media
bool loadMedia();

//Frees media and shuts down SDL
void close();

//The window we'll be rendering to
SDL_Window* gWindow = NULL;

//The surface contained by the window
SDL_Surface* gScreenSurface = NULL;

//The image we will load and show on the screen
SDL_Surface* gHelloWorld = NULL;

bool init()
{
    //Initialization flag
    bool success = true;

    //Initialize SDL
    if( SDL_Init( SDL_INIT_VIDEO ) < 0 )
    {
        printf( "SDL could not initialize! SDL_Error: %s\n", SDL_GetError() );
        success = false;
    }
    else
    {
        //Create window
        gWindow = SDL_CreateWindow( "SDL Tutorial", SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, SCREEN_WIDTH, SCREEN_HEIGHT, SDL_WINDOW_SHOWN );
        if( gWindow == NULL )
        {
            printf( "Window could not be created! SDL_Error: %s\n", SDL_GetError() );
            success = false;
        }
        else
        {
            //Get window surface
            gScreenSurface = SDL_GetWindowSurface( gWindow );
        }
    }

    return success;
}

bool loadMedia()
{
    //Loading success flag
    bool success = true;

    //Load splash image
    gHelloWorld = SDL_LoadBMP( "02_getting_an_image_on_the_screen/hello_world.bmp" );
    if( gHelloWorld == NULL )
    {
        printf( "Unable to load image %s! SDL Error: %s\n", "02_getting_an_image_on_the_screen/hello_world.bmp", SDL_GetError() );
        success = false;
    }

    return success;
}

void close()
{
    //Deallocate surface
    SDL_FreeSurface( gHelloWorld );
    gHelloWorld = NULL;

    //Destroy window
    SDL_DestroyWindow( gWindow );
    gWindow = NULL;

    //Quit SDL subsystems
    SDL_Quit();
}

int main( int argc, char* args[] )
{
    //Start up SDL and create window
    if( !init() )
    {
        printf( "Failed to initialize!\n" );
    }
    else
    {
        //Load media
        if( !loadMedia() )
        {
            printf( "Failed to load media!\n" );
        }
        else
        {
            //Apply the image
            SDL_BlitSurface( gHelloWorld, NULL, gScreenSurface, NULL );

            //Update the surface
            SDL_UpdateWindowSurface( gWindow );

            //Wait two seconds
            SDL_Delay( 2000 );
        }
    }

    //Free resources and close SDL
    close();

    return 0;
}

感谢所有帮助,谢谢;)

【问题讨论】:

  • “我读到你应该把你的代码分成几部分,这样它运行得更快更流畅”——这是完全错误的。它只能体现在更快的构建时间中。
  • 什么实际上不适用于您的方法。你能强调一下吗?
  • 您不应该包含 .cpp 文件 - 您通常会将所有 .cpp 编译为 .o 文件,然后将 .os 链接到 exe。在 game_state.h 中,除了包含 stdio(您不需要)之外,看起来您正在走上正轨。
  • 你可以通读this了解更多
  • 全局变量应该在game_state.cpp中声明,而不是在game_state.h中。如果您需要在主要使用它们,请在每个标题之前添加extern

标签: c++ sdl


【解决方案1】:

大项目被分成很多文件,这些文件通常映射到目录层次结构中。这样做的原因不是效率(如果将整个代码转储到单个文件中,编译实际上可能会更快,并且根本不会影响运行时间),而是代码管理问题(想象一下打开一个超过 100 000 行的文件代码)。

编程语言和工具通常旨在帮助这种做法。例如,在 C/C++ 中,您有 include 预处理器指令,它允许您“导入”文件。

关于如何执行实际拆分的问题,通常最好不要使用像您这样的自上而下的方法(即我有代码,我如何拆分它?)而是设计具有这种模块化的代码头脑。话虽如此,您可以将每个文件视为一个小模块,提供一些相关功能。这里有很多事情需要考虑,开发应用程序的架构是一门艺术,但现在,将具有相似功能的东西放在同一个地方是一个好的开始。

您的示例太小,无法提供任何实用建议,它是如此之小,以至于将所有内容都放在一个文件中并不是那么糟糕。您的划分很好,您分离了游戏逻辑(我不太喜欢您的模块名称game_state,因为您并没有真正代表那里的游戏状态;您似乎定义了一些与游戏相关的过程)但是没必要。

【讨论】:

    猜你喜欢
    • 2021-04-03
    • 1970-01-01
    • 2021-06-02
    • 1970-01-01
    • 1970-01-01
    • 2011-02-05
    相关资源
    最近更新 更多