2

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

我想要的伪代码可能如下所示:

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;
    }
}

起初,我考虑延长临时的生命周期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

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

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

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

4

3 回答 3

6

这是完全有效的:

static Foo fromInt(int v){
    Foo f;
    f.val = v;
    return f;
}

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

因此,如果您担心使用命名构造方法只是因为您不知道它是否有效,请继续使用它,它可以完美运行。

于 2012-07-06T16:06:22.490 回答
2

在 C++11 中,您可以从构造函数中调用其他构造函数:

struct X{
  X() : ... { ... }
  X(int i) : X() { ... }
  X(std::string s) : X() { ... }
};

对于 C++03,命名构造函数方法可能是最好的和完全合理的,恕我直言。

于 2012-07-06T16:07:10.187 回答
0

为什么不:

class Foo{
private:
    int val;
    void Init(int v = <some default value>/*What ever here *));
    /* ... */


public:
    // Base constructor
    Foo(){ Init(); }           // This provides basic initialization of 
    Foo(string &s) { Init(s.length); };
    Foo(int v) { Init(v); };
};

看起来更简单。

于 2012-07-06T16:06:01.133 回答