将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的返回值,不再是同一个数据。