防止物体立即被摧毁

The*_*rca 0 c++ singleton pointers

我试图创建一个类对象的单个实例,以便通过包含标头和调用方法的适当形式,使这个实例可以访问任何其他需要它的类getInstance().我试图通过遵循此处显示的Singleton示例来实现此目的,但由于某种原因,这个单个实例在创建后就会被销毁.

下面是头文件的副本, Window.h

#pragma once

#include <string>
#include <SDL.h>

class Window {

public:
    static Window* getInstance();
    static Window* getInstance(const std::string &title, int width, int height);
private:
    Window(const std::string &title, int width, int height);
    ~Window();

    bool init();

    std::string _title;
    int _width = 800;
    int _height = 600;

    SDL_Window *_window = nullptr;

    static Window *_instance;
    // static Window _solidInstance;
};
Run Code Online (Sandbox Code Playgroud)

下面是源文件,Window.cpp其中一些不相关的部分被删除以节省空间.

#include "Window.h"
#include <iostream>

Window* Window::instance = 0;
SDL_Renderer *Window::_renderer = nullptr;

Window::Window(const std::string &title, int width, int height) {
    // Code that isn't relevant to this issue
    std::cout << "Window constructor called\n";
}

Window::~Window() {
    // Code that isn't relevant to this issue
    std::cout << "Window destructor called\n";
}

Window* Window::getInstance() {
    return _instance;
}

Window* Window::getInstance(const std::string &title, int width, int height) {
    if (_instance == 0) {
        std::cout << "Just before construction\n";
        _instance = &Window(title, width, height);
        std::cout << "Just after construction\n";
        // _solidInstance = Window(title, width, height);
    }
    return _instance;
}
Run Code Online (Sandbox Code Playgroud)

构建并运行此代码后,以下行按以下顺序打印到控制台:

Just before construction
Window constructor called
Window destructor called
Just after construction
Run Code Online (Sandbox Code Playgroud)

这告诉我,我创建的Window实例在getInstance()有机会返回之前已经被破坏了.我不确定如何防止这种情况发生.我已经尝试使用Window的常规实例而不是指向一个(请参阅注释掉的代码行引用soldInstance)但这只是给我链接器错误.

任何帮助是极大的赞赏.

amc*_*176 7

你的问题在这里:_instance = &Window(title, width, height); 你正在获得一个临时窗口的地址,它在离开范围后会被破坏.

改为: _instance = new Window(title, width, height);

但是一定要在退出程序之前删除窗口!

一个更好的解决方案是在退出时自动删除窗口:

Window* Window::getInstance(const std::string &title, int width, int height) {
    static Window window{title, width, height};
    return &window;
}
Run Code Online (Sandbox Code Playgroud)