C++:`new`的奇怪行为

Mar*_*aux 1 c++ heap types sdl new-operator

SDL为我提供了这个结构:

typedef struct SDL_Rect {
    Sint16 x, y;
    Uint16 w, h;
} SDL_Rect;
Run Code Online (Sandbox Code Playgroud)

我想SDL_Rect在堆上创建一个新的类变量:

// Forward declaration
private:
    SDL_Rect *m_pcScreenRect;
Run Code Online (Sandbox Code Playgroud)

在构造函数中我这样做:

/* Screen Rectangle (for clearing) */
m_pcScreenRect = new SDL_Rect;
m_pcScreenRect->x = 0;
m_pcScreenRect->y = 0;
m_pcScreenRect->w = 800;
m_pcScreenRect->h = 600;
printf("Rect(x:%d, y:%d, w:%d, h:%d)\n", m_pcScreenRect->x, m_pcScreenRect->y, m_pcScreenRect->w, m_pcScreenRect->h);
Run Code Online (Sandbox Code Playgroud)

哪个打印Rect(x:0, y:0, w:800, h:600)
所以这是正确的.

问题1

但是,当我不初始化xy,它打印垃圾号码,如:

 Rect(x:-11280, y:63, w:800, h:600)
 Rect(x:25584, y:167, w:800, h:600)
 Rect(x:-11280, y:40, w:800, h:600)
 // This is just, run, terminate, run, terminate, ....
Run Code Online (Sandbox Code Playgroud)

我认为int的默认值是0

问题2

在我的游戏循环中,我有相同的行来检查SDL_Rect的值.在循环中,我得到如下结果:

Clear (x:0, y:40, w:0, h:560)
Clear (x:0, y:99, w:0, h:501)
Clear (x:0, y:55, w:0, h:545)
Clear (x:0, y:55, w:0, h:545)
// Again: run, terminate, run, terminate....
Run Code Online (Sandbox Code Playgroud)

当我的构造函数看起来像这样:

/* Screen Rectangle (for clearing) */
m_pcScreenRect = new SDL_Rect;
//m_pcScreenRect->x = 0;
//m_pcScreenRect->y = 0;
m_pcScreenRect->w = 800;
m_pcScreenRect->h = 600;
Run Code Online (Sandbox Code Playgroud)

当我取消注释这两行时,我得到了正常的结果:

/* Screen Rectangle (for clearing) */
m_pcScreenRect = new SDL_Rect;
m_pcScreenRect->x = 0;
m_pcScreenRect->y = 0;
m_pcScreenRect->w = 800;
m_pcScreenRect->h = 600;
Run Code Online (Sandbox Code Playgroud)

此问题是否new与数据类型(Uint16和普通int)有关.如果是数据类型,如何解决?

非常感谢! (哈哈!)

谢谢,
任何帮助将非常感谢!


额外问题:

我必须在C++中定义所有变量.
但随机数从何而来?

我使用g++gcc在Linux中.

Cub*_*bbi 5

为了使用"int的默认值",您可以使用值初始化:

m_pcScreenRect = new SDL_Rect(); // this will initialize to zeros
Run Code Online (Sandbox Code Playgroud)

否则,未定义值.

要提供更多详细信息:向此结构添加构造函数将是最好的方法,但由于它位于您(我猜)无法修改的第三方库中,您可以将其包装在您自己的提供默认构造函数的类中,或使用值初始化.引用C++ 03 8.5/5,

对值类型T的对象进行值初始化意味着:

  • 如果T是具有用户声明的构造函数的类类型,则调用T的默认构造函数

  • 如果T是没有用户声明的构造函数的非联合类类型,那么T的每个非静态数据成员和基类组件都是值初始化的;

  • 如果T是数组类型,那么每个元素都是值初始化的;

  • 否则,该对象被零初始化

在您的情况下,SDL_Rect是一个非联合类类型,没有用户声明的构造函数(此列表中的第二个子句),这意味着对其非静态数据成员执行值初始化,并且每个数据成员属于"否则为"子句,并且是零初始化(定义为"如果T是标量类型,则将对象设置为0(零)转换为T的值;")

  • @Martijn名称是"值初始化"(或"值初始化").这是C++ 98和C++ 03的主要区别. (2认同)
  • @Michael:`SDL_Rect`是一个POD,它只有内置函数,没有构造函数.对于这样的类型,"默认构造"和"值初始化"(或任何正确的术语)之间存在差异. (2认同)