C++中构造函数调用构造函数 最近在整理C++知识的时候,突然想到如何在C++中实现构造函数调用构造函数的问题,常见的错误是按照如下方式来调用: 1: #include 3: class Test 4: { 5: public: 6: int m_a; 8: Test(int a) 9: { 10: m_a = a; 11: } 13: Test() 14: { 15: Test(1); 16: } 17: }; 19: int main(int argc,char* argv[]) 20: { 21: Test var; 22: std::cout<<var.m_a<<std::endl; 23: return 0; 24: } 这段代码输出的是一个不确定的值! 代码奇怪的地方在于构造函数中调用了自己的另一个构造函数 我们知道,当定义一个对象时,会按顺序做2件事情: 1)分配好内存(非静态数据成员是未初始化的) 2)调用构造函数(构造函数的本意就是初始化非静态数据成员) 显然上面代码中,Test var;这里已经为var分配了内存,然后调用默认构造函数,但是默认构造函数还未执行完,却调用了另一个构造函数,这样相当于产生了一个匿名的临时对象,它调用Test(int)构造函数,将这个匿名临时对象自己的数据成员m_a初始化为1;但是var的数据成员并没有得到初始化。于是var的m_a是未初始化的,因此其值也是不确定的 那么如何在C++中实现构造函数调用构造函数呢? 这里需要说明一下new的另一种new的表达式----定位new表达式(placement new),它的作用是在已分配的原始内存中初始化一个对象,它与new的其他版本不同之处在于它并不分配内存。 STL中的原型如下: 1: void * operator new (size_t, const std::nothrow_t &) throw(); 2: void * operator new (size_t, void *) throw(); 3: void * operator new[] (size_t, const std::nothrow_t &) throw(); 4: void * operator new[] (size_t, void *) throw(); 该表达式的形式如下: 1: new (place_address) type 2: new (place_address) type (initializer-list) 其中place_address必须是一个指针,而intializer-list提供了(可能为空的)初始化立标,以便在构造新分配的对象时使用。 对于上面的例子,我们可以使用定位new表达式来完成构造函数之间的调用: 1: Test() 2: { 3: new (this) Test(1); 4: } 最后,对于构造函数相互调用的问题,可以考虑一下两点建议: 1)可以考虑使用构造函数的默认参数来减少这种调用方式。 2)如果仅仅为了一个构造函数重用另一个构造函数的代码,那么完全可以把构造函数中的公共部分抽取出来定义一个成员函数(推荐为private),然后在每个需要这个代码的构造函数中调用该函数即可。 附:C#中构造函数相互调用的例子 1: public class Base 2: { 3: int _a; 4: int _b; 5: 6: public Base() 7: { 8: _b = 2; 9: } 10: 11: public Base(int a) :this() 12: { 13: _a = a; 14: } 15: } 简单一点说就是this(params)语句
转载自:http://www.cnblogs.com/lidan/archive/2011/08/10/2239488.html
原文:http://www.cnblogs.com/leijiangtao/p/4677578.html