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,编译时编译器使用了默认的拷贝构造函数。