我正在寻找一种方法来定义一个“基础”构造函数,它将使用默认值初始化值,然后将该基础扩展为许多专门的构造函数。
我想要的伪代码可能是这样的:
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;
}
}
起初,我考虑过extending the lifetime of the temporary f
,但const声明阻止我编辑其成员。所以看来这已经结束了。
然后我尝试了"named constructor"方法(如上所示)。但是,我必须先修改示例以创建对象,然后修改它,然后返回它。这似乎有效,但我有理由相信这只是一个巧合,因为f
是一个临时的,并且在函数结束时超出了范围。
我也考虑使用像auto_ptr
这样的东西,但是我正在使用Foo对象以及auto_ptr
到Foo,这使得其余的代码“关心” “对象是通过基础构造函数创建的(在这种情况下它是一个对象),还是通过一个扩展构造函数(在这种情况下它将是一个指针)。
如果它有用,在Python中,我会使用这样的东西:
class Foo(object):
def __init__(self):
/* Basic initialization */
@classmethod
def fromString(cls, s):
f = Foo() #†
f.val = len(s)
return f
最后,我想用这种方式做两件事:
init()
类型私有方法来实现这一点,但我只是想提一下。fromSomething
语法提供了极好的清晰度。请原谅我,如果有一个简单的解决方案,我的工作在过去几年已从c ++转移到Java / Python,所以我有点生疏。
答案 0 :(得分:6)
这完全有效:
static Foo fromInt(int v){
Foo f;
f.val = v;
return f;
}
这会在您返回Foo
时调用f
的复制构造函数(可能编译器应用return value optimization,因此不会复制)。 f
超出了范围,但返回值只是它的副本,所以这是完全有效的,它不仅仅是“巧合”它的工作。
因此,如果你担心使用命名的构造函数方法只是你不知道它是否有效,那么继续它,它可以很好地工作。
答案 1 :(得分:2)
在C ++ 11中,您可以从构造函数中调用其他构造函数:
struct X{
X() : ... { ... }
X(int i) : X() { ... }
X(std::string s) : X() { ... }
};
对于C ++ 03,命名的构造函数方法可能是最好的,也是完全合理的,恕我直言。
答案 2 :(得分: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); };
};
似乎更简单。