现在的位置: 首页 > 综合 > 正文

在C++拷贝构造函数中使用初始化列表

2012年10月07日 ⁄ 综合 ⁄ 共 965字 ⁄ 字号 评论关闭

    今天同事遇到一个关于拷贝构造函数的问题。代码大致如下:

class test
{
	public:
		test( size_t size )
		{
			v.assign( size, 1 );
		}
		test( const test& rhs)
		{
			v = rhs.v;
		}
		~test(){}
	private:
		vector<int> v;
};

class another
{
	public:
		another()
		:v(7)
		{

		}
		another( const another& rhs )
		{
			v = rhs.v;
		}
		~another(){}
	private:
		test v;

};

 咋一看,貌似没有问题,但是gcc却编译不过去。报错如下:

在上面代码中,test类明明已经有构造函数和拷贝构造函数,为什么gcc一定要我给出一个默认构造函数出来呢?这个问题,就牵涉到了C++构造函数中的初始化列表问题了。

        在编写构造函数的时候,很多人都会意思到使用初始化列表来达到避免多次构造的资源损耗,但是,在编写拷贝构造函数的时候,我们大部分时间都是这样写的。

class test
{
     public:
           test():a(0){.....}
           test( const test& rs ){ a = rs.a; ...}
           ~test(){}
     private:
           int a;
};

而这就是造成这个问题的症结所在了。对于类而言,成员变量仅仅是声明一个变量,而真正的定义是在构造函数中做的,所以,如果在构造函数(包括拷贝构造函数)中,如果成员变量不是在初始化列表中进行初始化的话,像上面代码中的拷贝构造函数的写法,其实过程就相当于先调用一次默认构造函数对成员变量进行初始化,然后再调用=操作对成员变量进行赋值。因此,这就出现了上述gcc要求提供默认构造函数的问题了。

        为了解决这个问题,我们借助初始化列表这个很好的东东,把代码改成如下,问题就不见了。

class test
{
	public:
		test( size_t size )
		{
			v.assign( size, 1 );
		}
		test( const test& rhs)
			:v( rhs.v)
		{
		}
		~test(){}
	private:
		vector<int> v;
};

class another
{
	public:
		another()
		:v(7)
		{

		}
		another( const another& rhs )
			:v(rhs.v)
		{
		}
		~another(){}
	private:
		test v;

};

抱歉!评论已关闭.