C++构造函数是否可以返回指向相同对象的缓存版本的指针?

siotufzp  于 2022-12-01  发布在  其他
关注(0)|答案(2)|浏览(98)

假设我有一个类Bitmap,它有一个静态缓存Maptextures,其中包含指向所有已注册图像的指针。

class Bitmap {
public:
    Bitmap(const std::string &filename);

    // ... functionality ...

private:
// ... image data ...
    std::string filename;
    static std::map<std::string, std::unique_ptr<Bitmap>> images;
}

Bitmap的构造函数是否可以在缓存中搜索具有相同filename的现有对象,然后返回对该对象的引用?
我试过

if (images.find(filename) != images.end()) {
    *this = images[filename].get();
    return;
}

但这似乎不起作用。有没有办法使用构造函数来实现这种效果呢?

mbzjlibv

mbzjlibv1#

当你真正构造一个对象时,你已经超出了控制对象分配的范围,构造函数只是用来初始化对象。
一种以最少的程式码变更来达成此目的的方法,是将建构函式设为私用,并建立静态方法来执行建立/快取逻辑。

class Bitmap {
public:
    static Bitmap& Get(const std::string &filename);

private:
    Bitmap(const std::string &filename)
        : filename(filename)
    {
        std::cout << "Construct " << filename << "\n";
    }

    std::string filename;
    static std::map<std::string, std::unique_ptr<Bitmap>> images;
};

std::map<std::string, std::unique_ptr<Bitmap>> Bitmap::images;

Bitmap& Bitmap::Get(const std::string &filename)
{
    auto it = images.find(filename);
    if (it == images.end())
    {
        std::unique_ptr<Bitmap> ptr(new Bitmap(filename));
        it = images.insert(std::make_pair(filename, std::move(ptr))).first;
    }
    return *(it->second);
}

驱动程序代码:

int main()
{
    auto a = Bitmap::Get("foo");
    auto b = Bitmap::Get("bar");
    auto c = Bitmap::Get("foo");
}

输出量:

Construct foo
Construct bar

这实际上将Bitmap类变成了一个自我管理的缓存。如果你想允许缓存和未缓存的位图示例,那么你可以将缓存的东西移到一个单独的工厂类中,比如BitmapManager

9rnv2umw

9rnv2umw2#

让它工作的合理方法是将所有数据成员移动到一个结构体中,并将一个std::shared_ptr存储到Bitmap中(以及静态Map中)。

相关问题