C++赋值与初始化的区别

时间:2022-05-29 19:45:47

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”的声明


上面这个例子很好的证明了赋值和初始化的区别,在《Effective C++》第二部分详细的讨论了赋值和初始化的区别。

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