在我的程序中,我需要一个提供单独类实例的工厂函数,因为我需要控制每个实例的详细信息并了解一次存在多少个实例。特别是返回一个 std::shared_ptr 是理想的,但这最初是不可能的,因为 std::pointer 类型的“make”函数存在一个已知问题,因为它们也需要与我的 Widget 类成为朋友,这是'不可移植,因为它依赖于那些可能改变的方法的当前实现。
为了解决这个问题,我想使用 Passkey 成语,这是直接推荐用于这种情况的,如本文底部所述:https ://abseil.io/tips/134 。我的实施也基于在这里学到的经验教训:https ://arne-mertz.de/2016/10/passkey-idiom/
这是一个示例项目,它使用与我的完整项目相同的设置:
#include <iostream>
class Widget
{
public:
class Key
{
friend class Factory;
private:
Key() {};
Key(const Key&) = default;
};
int mTest;
explicit Widget(Key, int test) { mTest = test; }
int getTestVar() { return mTest; }
};
class Factory
{
public:
int mTestPass;
Factory(int input) { mTestPass = input; }
std::shared_ptr<Widget> factoryMake() { return std::make_shared<Widget>(Widget::Key{}, mTestPass); }
};
int main()
{
Factory testFactory(10);
std::shared_ptr<Widget> testWidget = testFactory.factoryMake();
std::cout << testWidget->getTestVar();
return 0;
}
但是,我得到
Error C2248 'Widget::Key::Key': cannot access private member declared in class 'Widget::Key' TestProject ...\include\xmemory 204
这让我完全迷失了,因为来自 xmemory.cpp 的错误表明 std::make_shared 仍在尝试访问私有构造函数。据我所知,Key实例的构造发生在属于Factory的factoryMake()函数中,然后将该实例传递给std::make_shared函数;因此,std::make_shared 不需要访问 Key 构造函数,因为已将构造的实例传递给它,这是在此上下文中使用此习惯用法的全部要点。该类本身是公共的,因此与 Key 类型交互应该没有问题,只有构造函数应该是不可访问的。
最后,我可以跳过使用 std::make_shared 而是使用带有原始指针的 shared_ptr(*T) 构造函数,但是由于它需要额外的分配,所以效率稍低,如我的第一个链接中所述。这没什么大不了的,因为我没有制作很多小部件,但我最终更愿意让更理想的实现工作。
我在这里想念什么?