第15章 《乐趣》Page305~311, 代码精简以后,讨论一下引用含义的问题

2023-12-17 04:50:33

将Page305~311的代码精简了一下,讨论一下引用含义的问题,精简之后的代码如下:

#include <iostream>
#include <SDL2/SDL.h>

using namespace std;

namespace sdl2
{

char const* last_error()
{
    return SDL_GetError();
}

struct Initiator
{
private:
    Initiator()//默认构造
        : _init_result(-1)
    {

    }
public:
    static Initiator& Instance()
    {
        static Initiator Instance;
        return Instance;
    }
    ~Initiator()
    {
        if(_init_result == 0)
        {
            SDL_Quit();
        }
    }

    void GetVersion(Uint8& major, Uint8& minor, Uint8& patch)
    {
        SDL_version ver;
        SDL_GetVersion(&ver);

        major = ver.major;
        minor = ver.minor;
        patch = ver.patch;
    }

    bool Init(Uint32 flags = SDL_INIT_EVERYTHING)
    {
        _init_result = SDL_Init(flags);
        return 0 == _init_result;
    }

//    bool operator bool()
    explicit operator bool() const
    {
        return _init_result == 0;
    }

private:
    int _init_result;
};//Initiator

struct WindowPosition
{
    WindowPosition() //默认构造,_x,_y都使用系统默认位置
            //SDL_WINDOWPOS_UNDEFINED会将窗口放到中间
        : _x(SDL_WINDOWPOS_UNDEFINED), _y(SDL_WINDOWPOS_UNDEFINED)
    {

    }

    //设置为居中,注意返回当前对象的引用
    WindowPosition& Centered(bool x_centered = true
                             , bool y_centered = true)
    {
        if(x_centered)
            _x = SDL_WINDOWPOS_CENTERED;
        if(y_centered)
            _y = SDL_WINDOWPOS_CENTERED;
    }

    int _x, _y;
};

struct WindowFlags
{
    WindowFlags() //默认构造,用于构建一个没有指定任何特性的普通窗口
        : _flags(0)
    {

    }

    Uint32 _flags;
};

struct Window
{
public:
    Window(char const* title
           , WindowPosition const& win_position
           , int w, int h
           , WindowFlags const& win_flags)
    {
        cout << &win_position << endl;
        _window = SDL_CreateWindow(title
                                   , win_position._x, win_position._y
                                   , w, h
                                   , win_flags._flags);
    }

    ~Window()
    {
        if(_window) //_window不是空指针
        {
            SDL_DestroyWindow(_window);
        }
    }

    SDL_Window* _window;
};

}

int main(int argc, char* argv[])
{
    sdl2::Initiator::Instance().Init(SDL_INIT_VIDEO
                                     | SDL_INIT_AUDIO
                                     | SDL_INIT_EVENTS
                                     | SDL_INIT_TIMER);

    if(!sdl2::Initiator::Instance())//重载转换符
    {
        cerr << "初始化就出错,没得玩了!"
             << sdl2::last_error() << endl;
        return -1;
    }

    //创建并居中显示宽640高480的游戏窗口
    sdl2::Window wnd("hello sdl"
                     , sdl2::WindowPosition().Centered(true, true)
                     , 640, 480
                     //使用空的特性标志
                     , sdl2::WindowFlags());
    SDL_Delay(5000);

    return 0;
}

可以看到代码第72和99行,使用了引用符号&,打两个断点,调试一下,当程序运行到75行时,停了下来,如下图:

说明72行,Centered函数返回的当前对象地址为0x61fe60, 继续运行到下一个断点,如下图

98行,构造函数中的参数win_position的地址是0x61fe60,这说明99行的参数win_position和72行Centered函数返回的当前对象的引用是同一个数据,继续往下执行,103行,输出了参数win_position的地址,果然是0x61fe60, 验证了我们的猜想。

若我们将99行的引用符号去掉,可以看到,72行的当前对象地址依然是0x61fe60

可是,99行的参数win_position,从调试中已看不到它的地址了,说明它只是一个复制的副本,再往下执行一行,可以看到参数win_position的地址是0x61fe3c ,这说明99行的参数win_position只是传入的复制量,和72的返回值,不再是同一个数据。

文章来源:https://blog.csdn.net/yanzhenxi/article/details/135040430
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。