调用其中一个成员函数时,在对象中调用“初始化”函数

时间:2017-02-20 10:49:48

标签: c++ c++11

我正在尝试在C ++中实现延迟初始化,并且当我调用Initialize()之类的其他方法时,我正在寻找一种调用object->GetName()成员函数的好方法。

现在我已按如下方式实施:

class Person
{
protected:
    bool initialized = false;
    std::string name;

    void Initialize()
    {
        name = "My name!"; // do heavy reading from database
        initialized = true;
    }

public:
    std::string GetName()
    {
        if (!initialized) {
            Initialize();
        }

        return name;
    }
};

这正是我目前所需要的。但是为每个方法设置初始化检查是非常繁琐的,所以我想摆脱它。如果有人在C ++中知道如何改进上面的例子,我想知道!

在使用operators时,可能会Initialize()用于实现调用->吗?

谢谢!

2 个答案:

答案 0 :(得分:2)

听起来像模板的工作!创建一个lazily_initialized包装器,它采用类型T功能对象 TInitializer类型:

template <typename T, typename TInitializer>
class lazily_initialized : TInitializer
{//                      ^^^^^^^^^^^^^^
 // inheritance used for empty-base optimization

private:
    T _data;
    bool _initialized = false;

public:
    lazily_initialized(TInitializer init = {}) 
        : TInitializer(std::move(init))
    {
    }

    T& get()
    {
        if(!_initialized)
        {
            static_cast<TInitializer&>(*this)(_data);
            _initialized = true;
        }

        return _data;
    }
};

您可以按如下方式使用它:

struct ReadFromDatabase
{
    void operator()(std::string& target) const
    {
        std::cout << "initializing...\n";
        target = "hello!";
    }
};

struct Foo
{
    lazily_initialized<std::string, ReadFromDatabase> _str;  
};

示例:

int main()
{
    Foo foo;
    foo._str.get(); // prints "initializing...", returns "hello!"
    foo._str.get(); // returns "hello!"
}

example on wandbox

在评论中提及Jarod42时,应使用std::optional<T>boost::optional<T>代替单独的bool字段,以表示&#34;未初始化状态&# 34 ;.这允许非默认构造类型与lazily_initialized一起使用,并且还使代码更优雅,更安全。

由于前者需要C ++ 17而后者需要boost,因此我使用单独的bool字段使我的答案尽可能简单。真正的实现应考虑使用optional,在适当的情况下使用noexcept,并考虑公开const - 合格的get(),其返回const T&

答案 1 :(得分:-2)

也许在构造函数中调用它?

编辑:呃,我错过了你的问题,抱歉。 懒惰的工厂初始化怎么样? https://en.wikipedia.org/wiki/Lazy_initialization#C.2B.2B