SDL2-如果未将我的颜色初始化为私有变量,为什么文本会闪烁?

问题描述 投票:0回答:1

我尝试用以下代码显示文本:

void Text::display(SDL_Renderer *renderer, int x, int y) {
// pos is an SDL_Rect and font is a TTF_Font
    pos.x = pos.w = x;
    pos.y = pos.h = y;

    SDL_Surface *surface = TTF_RenderText_Solid(font, text.c_str(), color);
    SDL_Texture *texture = SDL_CreateTextureFromSurface(renderer, surface);
    SDL_QueryTexture(texture, NULL, NULL, &pos.w, &pos.h);
    SDL_RenderCopy(renderer, texture, NULL, &pos);

    SDL_FreeSurface(surface);
    SDL_DestroyTexture(texture);
}

在我的[[Text类中。最初,我在SDL_Color color方法中有一个未初始化的Text::display(),可以在屏幕上显示文本。 (renderer从主坐标+ x,y传递)。但是我决定将SDL_Color color设为类Text中的私有变量。而且让我感到奇怪的是,作为私有变量,一旦我将其呈现,文本就会闪烁,但是如果我将其设置为公共变量或将其置于方法中,则文本不会闪烁。或者,如果我将其初始化为私有变量(SDL_Color color = {255, 255, 255})。

[我的问题是

color未被初始化为公共变量或方法变量时,是否只有纯粹的运气能起作用,或者是否将它们区别对待?当我在构造函数中初始化颜色时,如果颜色是私有的,它也会闪烁。

我的主要方法:

void fpsCap(Uint32 starting_tick) { if ((1000 / fps) > SDL_GetTicks() - starting_tick) { SDL_Delay(1000 / fps - (SDL_GetTicks() - starting_tick)); } } int main(int argv, char** args) { // Create renderer, window, etc while (true) { SDL_RenderClear(renderer); Text *txt = new Text("hello"); txt->display(gui->getRenderer(), 0, 0); SDL_RenderPresent(renderer); } }
c++ sdl sdl-2
1个回答
2
投票
私有成员的值未初始化,因此它将获得随机/垃圾值。当您为每个帧分配新的Text实例时。您在堆上分配(每次都在一个新位置),因此可以保证实际上是垃圾。

为什么在其他情况下没有闪烁?

  • 公众成员:我的猜测是您也将其设置为静态吗?静态变量是零初始化的(与成员变量相反)。
  • 局部变量:局部变量未清零并且被视为包含垃圾,但是由于它们是堆栈分配的,因此它们很可能在给定的位置每次都得到相同的垃圾。
  • 构造函数中分配的私有成员:这是意外的。您确定它与实际使用的构造函数相同吗?那是同一个变量吗?也许某些名称隐藏了该值,使该值无法实际降落到我们应该的位置?

切线:

您在每个循环中泄漏一个Text实例。您应该delete使用new创建的每个对象,或者更好的情况是,避免完全使用new。请改用unique_ptr / make_unique或仅使用局部变量(在这种情况下更好)。

编辑以回答有关new的问题:

在现代C ++中,您几乎几乎不需要使用new

  • 如果您有一个仅在函数执行期间使用的对象,自然要做的就是直接保留该对象(即不通过指针),在这种情况下,将变量定义为

    Text txt("hello");

    这是与Java的Text txt = new Text("hello");类似的用法,但是结果变量是实例本身,而不是对其的引用。]]

    [如果要创建一个实例,并立即将其作为Textconst Text&类型的参数传递,则可以像SomeFunction(Text("hello"))一样将其创建为临时实例(请注意,缺少new,它只是类名)。

  • 如果需要堆分配,则使用std::unique_ptrstd::unique_ptr创建的智能指针(std::shared_ptrstd::shared_ptr)为强烈建议使用它们,因为它们可以防止许多常见的陷阱,例如内存泄漏和指针悬空,至少只要您保持智能指针本身就行。 std::make_unique可能是标准C ++到Java参考的最接近的东西,尽管它不是垃圾回收的,所以如果循环执行它们,它们将永远不会被释放。
  • 您可以将std::make_unique替换为

    std::make_shared

得到相同的行为,但是std::make_shared被破坏并在该块的末尾释放。
© www.soinside.com 2019 - 2024. All rights reserved.