C++中, 对于简单类型的赋值和初始化的区别基本可以忽略,但当涉及到类或者复杂的数据类型时,问题就变得不那么简单了。
class Point { public: Point(int a=0, int b=0):x(a), y(b){}; ~Point(); Point& operator =(const Point &rhs); private: int x; int y; };
Point& Point::operator =(const Point &rhs) { x = rhs.x+1; y = rhs.y+1; return *this; }
在这个简单的Point类里,重载了“=”,在主函数中,对Point的实现分别做两个动作:
int main(void) { Point p(1,1); Point p1 = p; //初始化操作 Point p2; p2 = p; //赋值操作 std::cout<<"p1.x = "<<p1.x<<"\tp1.y = "<<p1.y<<std::endl; std::cout<<"p2.x = "<<p2.x<<"\tp2.y = "<<p2.y<<std::endl; return 0; }
p1.x = 1 p1.y = 1
p2.x = 2 p2.y = 2
而在初始化中的“=”调用的是默认的构造函数。
为了证明这一点,显示地声明一个private的拷贝函数(但不实现它):
class Point { private: Point(const Point &p); //注意此处传入函数必须是pass by ref,否则将引起无穷递归拷贝函数};
再次运行程序,报错:
1> main.cpp
1>c:\users\jia zhong\documents\visual studio 2010\projects\test\test\main.cpp(7): error C2248: “Point::Point”: 无法访问 private 成员(在“Point”类中声明)
1> c:\users\jia zhong\documents\visual studio 2010\projects\test\test\point.h(23) : 参见“Point::Point”的声明
1> c:\users\jia zhong\documents\visual studio 2010\projects\test\test\point.h(7) : 参见“Point”的声明
具体来说,C++中,当写下一个空类Empty时,就好像已经写下了下面的代码
class Empty { public: Empty(){} //default constructor
Empty(const Empty& rhs){} //copy constructor
~Empty(){} Empty& operator=(const Empty& rhs){} //overload copy assignment };
这些函数只有在需要调用的时候才会被编译器创建出来。在上述的Point的例子的初始化中,由于没有显示的声明和定义一个copy constructor,编译时编译器使用了默认的拷贝构造函数。