使用工厂朋友班分配新班,好的做法?

Posted

技术标签:

【中文标题】使用工厂朋友班分配新班,好的做法?【英文标题】:use factory friend class to allocate new class, good practice? 【发布时间】:2013-10-08 18:21:21 【问题描述】:

我有一个复杂的类,我想强制用户为其使用 std::unique_ptr,我认为最好的方法是创建一个返回 std::unique_ptr 的工厂方法并隐藏 ctor。

问题是,我添加的工厂方法越多,标题和代码看起来就越脏。

所以我想如果我创建一个包含所有工厂方法的新 ClassFactory 类,它看起来会更干净,每次我想添加新的工厂方法时,我只需编辑工厂类并完成它(保持原来的类干净)。

例如:

class Widget

private:
    friend class WidgetFactory;

    Widget()
    Widget(const Widget& other) = delete;
    Widget& operator = (const Widget& other) = delete;

    std::string _msg;

public:
    void printMessage() std::cout << _msg << std::endl; 
;

class WidgetFactory

public:
    static std::unique_ptr<Widget> create() auto w = std::unique_ptr<Widget>(new Widget);
                                             w->_msg = "hello world!"; return w; 
;

然后是用户:

int main(int argc, char** argv)

    auto w = WidgetFactory::create();
    w->printMessage();

另一种方法是使用私有令牌将 ctor 显式公开,以便我可以使用 std::make_shared/unique。

但我不记得以前见过这种模式,所以我的问题是,这是一种好的做法吗?你介意从你的同事那里看到这样的代码吗?

提前致谢。

【问题讨论】:

为什么不为Widget 定义移动构造函数和移动赋值运算符?然后你可以用右值设置一个 unique_ptr。 感谢您的回答。对不起,但我不明白这有什么帮助,我将在哪里设置一个带有右值的 unique_ptr?这意味着我必须构建所有 ctors(而不是工厂方法)并正确移动? 【参考方案1】:

不,这不是一个好习惯:

    您将无法为单元测试创​​建此类对象 - 您必须使用工厂 使用std::unique_ptr 表示一切都让人想起“当你有了一把新锤子,一切看起来都像钉子”这句话。很好用,但不能解决所有问题 auto 的代码看起来不错,但你不能用它来创建成员变量 对于大型(或至少是中型)项目,使用一个工厂处理所有事情会变得非常麻烦,并且会违背其目的

工厂模式很好(我个人喜欢它),但我不认为实际上每个对象都需要使用它来创建。

【讨论】:

感谢您的回答。从来没有考虑过单元测试这是一个好点。我知道这个类看起来很简单,但我正在研究的是一个 C 包装器,它有很多指针和对这些指针起作用的函数。所以我应该坚持构造函数?但是如果我得到了 10 个不同的构造函数,那不会让我的代码看起来更糟吗?复制和移动也不总是微不足道的,而且创建起来很痛苦,这就是我选择 std::unique_ptr 的原因 @sap 您仍然可以将工厂模式与 std::unique_ptr 一起使用,只是不要隐藏构造函数。并且不要为所有对象使用一个工厂。 @sap 通常,工厂将用于运行时多态性,例如创建具有公共接口的具体类。每个具体类都有一个create() 函数,工厂类将存储这些创建者的函数指针的注册表。可以在运行时探测注册表以查看必须将哪个特定的具体类分配给std::unique_ptr&lt;Base&gt;。创建者函数只返回一个std::make_unique&lt;Derived&gt;。但是您希望构造函数公开,因为知道要生成哪个类的客户端应该能够在没有unique_ptr 的情况下这样做。

以上是关于使用工厂朋友班分配新班,好的做法?的主要内容,如果未能解决你的问题,请参考以下文章

9月新班前端项目班:用React.js做一个IM即时通讯系统——饥人谷

传智播客成都java培训中心12月15日基础班开新班

传智播客成都java培训中心12月15日基础班开新班

朋友班:不能访问私人会员?

纯虚拟朋友班

华为机试真题 C++ 实现分班问题