类的初始化,用到的会有默认构造函数,带参构造函数和拷贝构造函数。(并不包含赋值函数)如下
class A
{
public:
A():x(0),y(0){};
A(int a, int b) :x(a), y(b){};
A(const A &other)
{
x = other.x;
y = other.y;
}
A &operator=(const A &other)//在初始化中没有用到
{
if (this == &other)
return *this;
x = other.x;
y = other.y;
return *this;
}
private:
int x;
int y;
};
类没有申请对象前是不分配内存的,实例可以是:
A a;//a.x=0,a.y=0
A b(3,4);//b.x=3,b.y=4;
A c(b);//c.x=3,c.y=4;
A d=c;//d.x=3,d.y=4;调用的是拷贝构造函数,并不是赋值函数
注意一点,A d=c; 调用的是拷贝构造函数,并不是赋值函数
让我们做个实验:(知识点----explicit关键字修饰构造函数说明只能显示调用,不能隐式调用)
class A
{
public:
A():x(0),y(0){};
A(int a, int b) :x(a), y(b){};
explicit A(const A &other)
{
x = other.x;
y = other.y;
}
A &operator=(const A &other)
{
x = other.x;
y = other.y;
return *this;
}
private:
int x;
int y;
};
A a;
A b=a;//报错
我以前一直以为成员变量的赋值只能通过构造函数等,因为实例前并没有分配内存。
但是,突然发现在类中,可以直接对成员变量进行赋值,如下
class A
{
public:
A(){};
private:
int x=5;
int y=6;
};
A a;//a.x=5,a.y=6;
直接赋值可以,和其他构造函数没有冲突,但是我没有想明白的是内存问题。等有答案了想起来再来编辑下。
还有一个知识点要记得是为什么赋值函数形式如上:
- 为实现连续赋值,如a=b=c; 就是实现c赋值给b后,b可以再次将值赋值给a;
- & operator=和 return *this;的目的是为了避免产生临时对象,直接将赋值后的对象返回,提高程序的效率。
所以,若你并不想实现连续赋值时,构造函数可以写成如下,让我们做一个双倍的赋值函数
class A
{
public:
A() :x(0), y(0){};
A(int a, int b) :x(a), y(b){};
A(const A &other)
{
x = other.x;
y = other.y;
}
void operator=(const A &other)
{
x = 2*other.x;
y = 2*other.y;
}
private:
int x;
int y;
};
A a(5,6);
A b;
b=a;//b.x=10,b.y=12
A c;
c=b=a;//报错
在 重载= 函数中,我把每个值都乘以了2