类 || 的终身问题实例如何构建我的复制构造函数?

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

我的问题在于在我的项目中创建类的实例。 这就是我创建实例并尝试存储它们的方式:

    for (const auto & entry : fs::directory_iterator(path))
    {
        auto x = path + "/" + std::filesystem::path(entry).filename().string();
        auto y = x.c_str();
        Texture text(y);
        inGameTextures.push_back(text);
    }

目标是从特定目录加载所有图像作为纹理并将它们全部存储在列表中。

我发现这不起作用,第一个加载的图像总是被后面的图像覆盖。 这以及纹理根本没有显示在屏幕上的事实一定与实例的生命周期有关,因为我是从函数创建所有实例的。 我发现我的类可能需要一个复制构造函数,因此我尝试添加一个基本复制并将构造函数移动到我的标题中:

    Texture(const char* path);
    Texture(const Texture& other) :
    texture(other.texture){};
    Texture& operator=(const Texture & that)
    {texture = that.texture;};
    Texture(Texture &&) noexcept = default;
    Texture& operator=(Texture &&) noexcept = default;
    ~Texture();

当然这也不起作用,但我无法真正了解复制构造函数的设置以及我到底需要它复制什么才能使其正常工作。 我希望有人能给我提示这些复制/移动构造函数有什么问题以及如何正确构建我的构造函数,以及任何提示我的代码还有什么问题,因为它们都没有真正起作用。

为了让您探索我在“纹理”课程中尝试做的事情,这是我的标题:

class Texture {
    private:
        unsigned int texture = 0;
    public:
        Texture(const char* path);
        Texture(const Texture& other) :
        texture(other.texture){};
        Texture& operator=(const Texture & that)
        {texture = that.texture;};
        Texture(Texture &&) noexcept = default;
        Texture& operator=(Texture &&) noexcept = default;
        ~Texture();

        int LoadImage(const char* path);
        void CustomizeTexture();

        struct data
        {
            std::string name;
            std::string documentExtension;
            glm::vec3 position;
            int ID;
        };

        static data& GetTextureData();
        static void SetData(const char* path);
        void SetID(int ID);
        static float RandomPositionValue();

        //int GetWidth() const { return width; };
        //int GetHeight() const { return height; };
    };

这就是我的 .cpp 的主要作用:

Texture::data textureData;

Texture::Texture(const char* path) :
texture(0)
{
    textureData.ID = LoadImage(path);
    SetData(path);
}

对于新手错误,深表歉意,希望有人能帮助我:) 提前致谢! :)

c++ class constructor instance copy-constructor
1个回答
0
投票

正如评论者已经指出的那样,您管理

Texture
资源的方式已被破坏。您手动提供复制构造函数和析构函数,但移动操作仍然是默认的,这是没有意义的,因为默认的移动操作可以绕过您通常的手动管理。

由于

glGenTextures
返回的纹理 ID 无论如何都不可复制(不存在
glCopyTexture
),因此建模唯一所有权更有意义:

// note: prefer GLuint over unsigned int.
//       GLuint is a 32-bit unsigned integer so the closest thing would be
//       std::uint32_t, wheras unsigned int can be 16 bits or any greater width.
GLuint texture;

Texture(Texture &&other) noexcept
  : texture(std::exchange(other.texture, 0))
{}

Texture& operator=(Texture &&other) noexcept {
    texture = std::exchange(other.texture, 0);
    return *this;
}

~Texture() {
    // I'm 50% sure that you cannot delete the zero object, so let's check
    if (texture != 0)
        glDeleteTextures(1, &texture);
}

// optional, these are implicitly deleted
Texture(Texture const&) = delete;
Texture& operator=(Texture const&) = delete;

不幸的是,我们无法删除

std::unique_ptr
的工作,因为
GLuint
不是NullablePointer

除了资源管理问题之外,很难说还有什么问题。也许是这个,也许不是。您还没有提供最小的可重现示例。

© www.soinside.com 2019 - 2024. All rights reserved.