命名构造函数和临时生命周期扩展

jed*_*rds 3 c++ named-constructor

我正在寻找一种方法来定义一个"基础"构造函数,它将使用默认值初始化值,然后将该基础扩展为许多专门的构造函数.

我想要的伪代码可能是这样的:

class Foo{
private:
    int val;
    /* ... */

public:
    // Base constructor
    Foo(){ /*...*/ }           // This provides basic initialization of members

    // Named constructors
    static Foo fromString(string s){
        Foo f;                 // Call base constructor
        f.val = s.length();    // Customize base object
        return f;              // Return customized object
    }
    static Foo fromInt(int v){
        Foo f;
        f.val = v;
        return f;
    }
}
Run Code Online (Sandbox Code Playgroud)

起初,我考虑延长临时的生命周期f,但const声明阻止我编辑其成员.所以看来这已经结束了.

然后我尝试了"命名构造函数"方法(如上所示).但是,我必须先修改示例以创建对象,然后修改它,然后返回它.这似乎有效,但我有理由相信它只是一个巧合,因为它f是一个临时的,并且在函数结束时超出了范围.

我也考虑使用像auto_ptrs 这样的东西,但是我正在使用Foo对象以及auto_ptrs到Foo,这使得其余的代码"关心"对象是否通过基础构造函数创建(在这种情况下)它将是一个对象)或通过一个扩展构造函数(在这种情况下它将是一个指针).

如果它有用,在Python中,我会使用这样的东西:

class Foo(object):
    def __init__(self):
        /* Basic initialization */

    @classmethod
    def fromString(cls, s):
        f = Foo() #†
        f.val = len(s)
        return f
Run Code Online (Sandbox Code Playgroud)

最后,有两个原因我想这样做:

  1. 代码重用,我想将每个构造函数的公共初始化移动到一个.我意识到我可以init()通过每个构造函数调用的类型私有方法来实现这一点,但我只想提一下.
  2. 清晰并解决歧义.与命名构造函数示例的动机非常相似,参数类型本身不足以确定应该使用哪个ctor.此外,fromSomething语法提供了极好的清晰度.

请原谅我,如果有一个简单的解决方案,过去几年我的工作已从c ++转移到Java/Python,所以我有点生疏了.

mfo*_*ini 6

这完全有效:

static Foo fromInt(int v){
    Foo f;
    f.val = v;
    return f;
}
Run Code Online (Sandbox Code Playgroud)

这会Foo在您返回时调用复制构造函数f(可能编译器应用返回值优化,因此不会复制).f超出范围,但返回值只是它的副本,所以这是完全有效的,它不仅仅是"巧合",它正在发挥作用.

因此,如果你担心使用命名的构造函数方法只是你不知道它是否有效,那么继续它,它完美地工作.