[英]Named constructors and temporary lifetime extension
I'm looking for a way to define a "base" constructor, that will initialize values using defaults, and then extend that base into a number of specialized constructors. 我正在寻找一种方法来定义一个“基础”构造函数,它将使用默认值初始化值,然后将该基础扩展为许多专门的构造函数。
The pseudocode of what I want might look like: 我想要的伪代码可能是这样的:
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;
}
}
At first, I thought about extending the lifetime of the temporary f
, but the const declaration prevents me from editing its members. 起初,我考虑过延长临时
f
的生命周期 ,但const声明阻止我编辑其成员。 So it seems this is out. 所以看来这已经结束了。
Then I tried the "named constructor" approach (which is shown above). 然后我尝试了“命名构造函数”方法(如上所示)。 However, I had to modify the example to create the object first, then modify it, then return it.
但是,我必须先修改示例以创建对象,然后修改它,然后返回它。 This seems to work, but I'm reasonably confident that it is just a coincidence since
f
is a temporary and goes out of scope at the end of the function. 这似乎有效,但我有理由相信这只是一个巧合,因为
f
是一个临时的,并且在函数结束时超出了范围。
I've also considered using something like auto_ptr
s, but then I'm working with both Foo objects as well as auto_ptr
s to Foo, and this makes the rest of the code "care" whether objects are created via the base constructor (in which case it would be an object) or via one of the extended constructors (in which case it would be a pointer). 我也考虑过使用类似
auto_ptr
的东西,但后来我正在使用Foo对象和auto_ptr
到Foo,这使得其余的代码“关心”对象是否通过基础构造函数创建(在在哪种情况下它将是一个对象)或通过一个扩展构造函数(在这种情况下它将是一个指针)。
If it helps, in Python, I would use something like this: 如果它有用,在Python中,我会使用这样的东西:
class Foo(object):
def __init__(self):
/* Basic initialization */
@classmethod
def fromString(cls, s):
f = Foo() #†
f.val = len(s)
return f
Lastly, there are two reasons I want to do it this way: 最后,有两个原因我想这样做:
init()
-type private method called by each constructor, but I just wanted to mention this. init()
类型私有方法来做到这一点,但我只想提一下。 fromSomething
syntax provides excellent clarity. fromSomething
语法提供了极好的清晰度。 Forgive me if there is a simple solution, my work has shifted from c++ to Java/Python for the past few years so I'm a bit rusty. 请原谅我,如果有一个简单的解决方案,过去几年我的工作已从c ++转移到Java / Python,所以我有点生疏了。
This is perfectly valid: 这完全有效:
static Foo fromInt(int v){
Foo f;
f.val = v;
return f;
}
This invokes Foo
's copy constructor when you return f
(probably the compiler applies return value optimization , so no copies are made). 这会在您返回
f
时调用Foo
的复制构造f
(可能编译器应用返回值优化 ,因此不会生成副本)。 f
goes out of scope, but the return value is just a copy of it, so this is totally valid, it's not just "a coincidence" that it's working. f
超出范围,但返回值只是它的副本,所以这是完全有效的,它不仅仅是“巧合”,它正在发挥作用。
So if your worries about using the named constructor approach is just that you don't really know if it works, go ahead with it, it works perfectly. 因此,如果你担心使用命名的构造函数方法只是你不知道它是否有效,那么继续它,它完美地工作。
In C++11, you can call other constructors from constructors: 在C ++ 11中,您可以从构造函数中调用其他构造函数:
struct X{
X() : ... { ... }
X(int i) : X() { ... }
X(std::string s) : X() { ... }
};
For C++03, the named constructor approach is likely the best and perfectly reasonable, IMHO. 对于C ++ 03,命名的构造函数方法可能是最好的,也是完全合理的,恕我直言。
Why not: 为什么不:
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); };
};
Seems simpler. 似乎更简单。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.