gpt4 book ai didi

C++11 案例研究 : How to implement factory design with smartpointers? [示例和测试]

转载 作者:行者123 更新时间:2023-11-30 03:47:40 26 4
gpt4 key购买 nike

这是一个在 C++11 中使用工厂设计模式的案例研究。如果有人能解释修复尝试中实际发生的情况,我将很高兴:

基本设计

假设我们想从工厂获取我们不想显式保存的元素,但我们想确保它们被正确删除。我用谷歌搜索了示例,但我似乎没有找到任何示例,所以我们需要做一些测试:

我认为我们可以实现目标的方法是使用 std::unique_ptr 对象来处理所有删除任务。在这里我只喜欢 unique_ptr 而不是 shared_ptr,因为它会在离开范围时调用持有元素的析构函数,因此使用它会使任何隐藏的复制可见。首先让我们创建一个能够创建 lambda 函数的简单工厂:

class To_do_base
{
public:
std :: function<void()> what_to_do;
To_do_base() {};
virtual ~To_do_base() { std :: cout << "~To_do_base()..." << std :: endl; };
std :: function<void()>& get_function() { return this -> what_to_do; };
};


class Special_to_do : public To_do_base
{
public:
Special_to_do()
{
this -> what_to_do = []()
{
std :: cout << "I have a special thing for you to do!" << std :: endl;
};
};
~Special_to_do() { std :: cout << "~Special_to_do()..." << std :: endl; };
};

所以现在每当我们调用Special_to_do() 构造函数时,我们都会生成一个函数来打印“我有一件特别的事情要你做!”。现在让我们创建一个工厂来为我们实例化这些类:

class To_do_factory
{
public:
static std :: unique_ptr<To_do_base> get_to_do( const std :: string& keyword_p )
{
if( keyword_p == "special" )
{
return std :: unique_ptr<To_do_base>( new Special_to_do() );
}
std :: cerr << "Error: Argument_factory::get_argument()..." << std :: endl;
return nullptr;
};
};

现在让我们创建一个 main() 并祈祷吧!

int main()
{
To_do_factory :: get_to_do( "special" ) -> get_function()();
return 0;
}

程序输出:

I have a special thing for you to do!
~Special_to_do()...
~To_do_base()...

问题

到目前为止一切顺利。但是让我们通过先保存函数然后再调用它来仔细检查结果:

int main()
{
std :: function<void()> to_do = To_do_factory :: get_to_do( "special" ) -> get_function();
to_do();
return 0;
}

程序输出:

~Special_to_do()...
~To_do_base()...
I have a special thing for you to do!

所以看起来现在的返回值实际上是最初创建的函数的一个拷贝。为什么这很糟糕?通常,当您传递 lambda 函数时,它们会捕获其范围内的一些变量(例如 this)。但是,在复制它们时,这些变量可能会超出范围,从而导致不太严重的段错误。


我有一个答案,其中我写下了我到目前为止推断的所有内容,以及一种“破解”此设计的方法。但我不知道我在那里做了什么,这只是一个案例研究。请帮助我了解那里出了什么问题。谢谢!

最佳答案

如果我理解,问题是如果 lambda 被存储、复制等,如何防止 lambda 捕获的变量超出范围(已经被破坏)。

这里有两个建议。

Lambda 经常是回调。在超出范围之前,对象从将回调它的服务中注销自己。

或者,lambda 捕获的所有指针(其生命周期显然不安全)都应该是 shared_ptr。如果在调用 lambda 时对象确实始终可用,那么这很好。你可能会发现 http://en.cppreference.com/w/cpp/memory/enable_shared_from_this有益的讨论。

关于C++11 案例研究 : How to implement factory design with smartpointers? [示例和测试],我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33587510/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com