Chinaunix首页 | 论坛 | 博客
  • 博客访问: 336709
  • 博文数量: 79
  • 博客积分: 2466
  • 博客等级: 大尉
  • 技术积分: 880
  • 用 户 组: 普通用户
  • 注册时间: 2006-02-07 16:47
文章分类

全部博文(79)

文章存档

2014年(3)

2012年(7)

2011年(14)

2010年(2)

2009年(2)

2008年(2)

2007年(18)

2006年(31)

分类: C/C++

2011-09-18 20:58:30

从开始学C++就一直记得“如果一个类没有定义拷贝构造函数或者赋值操作符,编译器会为它生成一个拷贝构造函数和一个赋值操作符。”

这个说法其实挺含糊的。今天看书的时候看到的一个例子,就让我感到十分“出乎意料”。

#include

struct X
{
  X() { };

  template
  X( const T& ) {
    printf("templated X copy constructor.");
  }

  template
  X& operator=( const T& ) {
    printf("templated X assignment operator.");
  }
};

int
main(int argc, char** argv) {
  X x1;
  X x2(x1);
  X x3;
  x3 = x1;
}

这个程序编译后,执行结果是啥?答案:啥也没有!两个函数模板都没有被调用到。
原因说起来并不十分复杂,但能看出,我对C++的细节还是不够清楚。好,现在细节来了:

C++标准(ISO/IEC 14882:2003(E))12.8.2写的清楚:
A non-template constructor for class X is a copy constructor if its first parameter is of type X&, const X&, volatile X& or const volatile X&, and either there are no other parameters or else all other parameters have default arguments (8.3.6).
要点:带有模板参数的函数模板,不算是构造函数。
所以上面例子中声明的template X(const T&)这个函数不是拷贝构造函数。
并且按照这段话对拷贝构造函数的定义,上面的类定义里没有显式地定义任何拷贝构造函数。

C++标准接着说:If the class definition does not explicitly declare a copy constructor, one is declared implicitly.
这个是学过C++的人基本都知道的事情。所以编译器要为上面的类生成一个隐式的拷贝构造函数。

编译器生成的隐式拷贝构造函数,所做的事情就是对类的所有成员一一做浅拷贝,自然没有任何输出。

赋值操作符的情形类似。标准定义为:
A user-declared copy assignment operator X::operator= is a non-static non-template member function of class X with exactly one parameter of type X, X&, const  X&, volatile  X& or const  volatile X&.
即:赋值操作符必须是一个非模板的、非静态的成员函数,而且只能有一个参数。这一点和拷贝构造函数还不同。拷贝构造函数可以有多个参数,只要第一个是X&或者cv-qualified X&类型,而其后的所有参数都有缺省值即可。

程序真正执行的时候,两个函数模板均未被调用到,所以什么输出也没有。
阅读(573) | 评论(0) | 转发(0) |
0

上一篇:Java内存泄漏调试

下一篇:做题得到的教训

给主人留下些什么吧!~~