C++派生类的赋值运算符重载详细说明【C++】(zo)

派生类的赋值符重载

赋值运算符函数,不是构造器,可以看作是一个普通的函数,所以可以继承,语法上就
没有构造器那么严格。

情况分析

父类和子类都是系统默认

#include <iostream>

using namespace std;

class A
{
public:
	A(string x = " ")
	{
		a = x;
		cout << "A()" << endl;
	}
	string a;
};

class B:public A
{
public:
	B(string x , string y)
		:A(x)
	{
		b = y;
		cout << "B()" << endl;
	}
	string b;
};

int main()
{
	B b("b1","b2");
	B bb("bb1","bb2");	
bb = b;
	cout << "bb.a:" << bb.a << endl;
	cout << "bb.b:" << bb.b << endl;

    return 0;
}

执行结果为:
运行结果

我们可以看到默认情况下,父类和子类的赋值运算符重载都调用成功。

子类系统默认,父类自实现赋值运算符重载

#include <iostream>

using namespace std;

class A
{
public:
	A(string x = " ")
	{
		a = x;
		cout << "A()" << endl;
	}
	A& operator=(const A& another)
	{
		this->a = another.a;
		cout << "A & operator=(const A & another)" << endl;
		return *(this);
	}
	string a;
};

class B:public A
{
public:
	B(string x , string y)
		:A(x)
	{
		b = y;
		cout << "B()" << endl;
	}

	string b;
};

int main()
{
	B b("b1","b2");
	B bb("bb1","bb2");
	bb = b;
	cout << "bb.a:" << bb.a << endl;
	cout << "bb.b:" << bb.b << endl;

    return 0;
}

运行结果:

执行结果

上面的代码中,父类自实现的赋值运算符重载函数和系统默认提供的赋值运算符重载函数的功能是一样的,只不过我们多了一个cout输出语句。
我们可以看到先调用父类自实现的赋值运算符重载函数,然后子类调用系统默认提供赋值运算符重载函数。

父类系统默认,子类自实现赋值运算符重载

#include <iostream>

using namespace std;

class A
{
public:
	A(string x = " ")
	{
		a = x;
		cout << "A()" << endl;
	}
	string a;
};

class B:public A
{
public:
	B(string x , string y)
		:A(x)
	{
		b = y;
		cout << "B()" << endl;
	}

	B & operator=(const B& another)
	{
		if (this == &another)      //判断是否是自赋值
			return *this;
		cout << "B & operator=(const B & another)" << endl;
		A::operator=(another);     //继承赋值运算符重载函数
		this->b = another.b;
		return *this;
	}
	string b;
};

int main()
{
	B b("b1","b2");
	B bb("bb1","bb2");
	bb = b;
	cout << "bb.a:" << bb.a << endl;
	cout << "bb.b:" << bb.b << endl;

    return 0;
}

运行结果;

运行结果

父类系统默认,子类自实现赋值运算符重载的时候,先调用父类的默认,然后调用子类自实现赋值运算符重载。

子类和父类都自实现赋值运算符重载

#include <iostream>

using namespace std;

class A
{
public:
	A(string x = " ")
	{
		a = x;
		cout << "A()" << endl;
	}
	A& operator=(const A& another)
	{
		this->a = another.a;
		cout << "A & operator=(const A & another)" << endl;
		return *(this);
	}
	string a;
};

class B:public A
{
public:
	B(string x , string y)
		:A(x)
	{
		b = y;
		cout << "B()" << endl;
	}

	B & operator=(const B& another)
	{
		if (this == &another)      //判断是否是自赋值
			return *this;
		cout << "B & operator=(const B & another)" << endl;
		this->b = another.b;
		return *this;
	}
	string b;
};

int main()
{
	B b("b1","b2");
	B bb("bb1","bb2");
	bb = b;
	cout << "bb.a:" << bb.a << endl;
	cout << "bb.b:" << bb.b << endl;

    return 0;
}

运行结果为:

运行结果

父类和子类都自实现赋值运算符重载函数的时候,只调用子类的赋值运算符重载不调用父类的赋值运算符函数,那就失去了赋值的意义。

那么我们如果解决?

父类显式调用

我们前面说过,赋值运算符重载已经被继承,所以我们可以在子类直接调用父类的赋值运算符重载函数。

语法

子类& 子类::operator=(const 子类& another)
{
...
父类::operator =(another); // 调用父类的赋值运算符重载
...
}

赋值顺序

图示

赋值运算符复制顺序

注解

赋值运算符重载注解

代码演示

#include <iostream>

using namespace std;

class A
{
public:
	A(string x = " ")
	{
		a = x;
		cout << "A()" << endl;
	}
	A& operator=(const A& another)
	{
		this->a = another.a;
		cout << "A & operator=(const A & another)" << endl;
		return *(this);
	}
	string a;
};

class B:public A
{
public:
	B(string x , string y)
		:A(x)
	{
		b = y;
		cout << "B()" << endl;
	}

	B & operator=(const B& another)
	{
		if (this == &another)      //判断是否是自赋值
			return *this;
		cout << "B & operator=(const B & another)" << endl;
		A::operator=(another);     //继承赋值运算符重载函数
		this->b = another.b;
		return *this;
	}
	string b;
};

int main()
{
	B b("b1","b2");
	B bb("bb1","bb2");
	bb = b;
	cout << "bb.a:" << bb.a << endl;
	cout << "bb.b:" << bb.b << endl;

    return 0;
}

运行结果:
执行结果

上面代码中:

B & operator=(const B& another)
	{
		if (this == &another)      //判断是否是自赋值
			return *this;
		cout << "B & operator=(const B & another)" << endl;
		A::operator=(another);     //继承赋值运算符重载函数
		this->b = another.b;
		return *this;
	}

A::operator=(another); 必须加上A:: 作用域是不能省略的。
否则B的赋值运算符重载函数就会和里面的operator=(another);同名,那就是自己调用自己实现了递归。

代码演示:

#include <iostream>

using namespace std;

class A
{
public:
	A(string x = " ")
	{
		a = x;
		cout << "A()" << endl;
	}
	A& operator=(const A& another)
	{
		this->a = another.a;
		cout << "A & operator=(const A & another)" << endl;
		return *(this);
	}
	string a;
};

class B:public A
{
public:
	B(string x , string y)
		:A(x)
	{
		b = y;
		cout << "B()" << endl;
	}

	B & operator=(const B& another)
	{
		if (this == &another)      //判断是否是自赋值
			return *this;
		cout << "B & operator=(const B & another)" << endl;
		operator=(another);     //继承赋值运算符重载函数
		this->b = another.b;
		return *this;
	}
	string b;
};

int main()
{
	B b("b1","b2");
	B bb("bb1","bb2");
	bb = b;
	cout << "bb.a:" << bb.a << endl;
	cout << "bb.b:" << bb.b << endl;

    return 0;
}

运行结果:
执行结果

就会进入死循环。

内嵌子对象

子类使用系统默认,内嵌子对象类也使用系统默认

#include <iostream>

using namespace std;


class C
{
public:
	C(string z = "0")
	{
		c = z;
		cout << "C()" << endl;
	}
	string c;
};





class A
{
public:
	A(string x = " ")
	{
		a = x;
		cout << "A()" << endl;
	}
	string a;
};

class B:public A
{
public:
	B(string x , string y, string z)
		:A(x),c(z)
	{
		b = y;
		cout << "B()" << endl;
	}

	C c;
	string b;
};

int main()
{
	B b("b1","b2","b3");
	B bb("bb1","bb2","bb3");
	bb = b;
	cout << "bb.a:" << bb.a << endl;
	cout << "bb.b:" << bb.b << endl;
	cout << "bb.c.c:" << bb.c.c << endl;

    return 0;
}

执行结果为:

执行结果

我们可以看到子类和内嵌子对象都使用默认的时候,系统会调用子类和内嵌子对象的系统默认赋值运算符重载函数。

子类是系统默认,内嵌子对象类自实现赋值运算符重载函数。

#include <iostream>

using namespace std;


class C
{
public:
	C(string z = "0")
	{
		c = z;
		cout << "C()" << endl;
	}
	C& operator=(const C& another)
	{
		this->c = another.c;
		cout << "C & operator=(const C & another)" << endl;
		return *(this);
	}
	string c;
};





class A
{
public:
	A(string x = " ")
	{
		a = x;
		cout << "A()" << endl;
	}
	string a;
};

class B:public A
{
public:
	B(string x , string y, string z)
		:A(x),c(z)
	{
		b = y;
		cout << "B()" << endl;
	}
	C c;
	string b;
};

int main()
{
	B b("b1","b2","b3");
	B bb("bb1","bb2","bb3");
	bb = b;
	cout << "bb.a:" << bb.a << endl;
	cout << "bb.b:" << bb.b << endl;
	cout << "bb.c.c:" << bb.c.c << endl;

    return 0;
}

运行结果为:
执行结果

这个时候默认调用内嵌子对象的赋值运算符重载函数,然后默认调用子类系统默认提供的赋值运算符重载函数。

子类是自实现赋值运算符重载函数,内嵌子对象类系统默认

#include <iostream>

using namespace std;


class C
{
public:
	C(string z = "0")
	{
		c = z;
		cout << "C()" << endl;
	}
	
	string c;
};





class A
{
public:
	A(string x = " ")
	{
		a = x;
		cout << "A()" << endl;
	}
	
	string a;
};

class B:public A
{
public:
	B(string x , string y, string z)
		:A(x),c(z)
	{
		b = y;
		cout << "B()" << endl;
	}

	B & operator=(const B& another)
	{
		if (this == &another)      //判断是否是自赋值
			return *this;
		cout << "B & operator=(const B & another)" << endl;
		A::operator=(another);     //继承赋值运算符重载函数
		this->b = another.b;
		return *this;
	}
	C c;
	string b;
};

int main()
{
	B b("b1","b2","b3");
	B bb("bb1","bb2","bb3");
	bb = b;
	cout << "bb.a:" << bb.a << endl;
	cout << "bb.b:" << bb.b << endl;
	cout << "bb.c.c:" << bb.c.c << endl;

    return 0;
}

执行结果为:

执行结果

我们可以看到子类会调用自实现赋值运算符重载函数,内嵌子对象类不会调用系统默认提供的赋值运算符重载函数。

子类和内嵌子对象类都自实现赋值运算符重载函数。

#include <iostream>

using namespace std;


class C
{
public:
	C(string z = "0")
	{
		c = z;
		cout << "C()" << endl;
	}
	C& operator=(const C& another)
	{
		this->c = another.c;
		cout << "C & operator=(const A & another)" << endl;
		return *(this);
	}
	string c;
};





class A
{
public:
	A(string x = " ")
	{
		a = x;
		cout << "A()" << endl;
	}
	//A& operator=(const A& another)
	//{
	//	this->a = another.a;
	//	cout << "A & operator=(const A & another)" << endl;
	//	return *(this);
	//}
	string a;
};

class B:public A
{
public:
	B(string x , string y, string z)
		:A(x),c(z)
	{
		b = y;
		cout << "B()" << endl;
	}

	B & operator=(const B& another)
	{
		if (this == &another)      //判断是否是自赋值
			return *this;
		cout << "B & operator=(const B & another)" << endl;
		A::operator=(another);     //继承赋值运算符重载函数
		this->b = another.b;
		return *this;
	}
	C c;
	string b;
};

int main()
{
	B b("b1","b2","b3");
	B bb("bb1","bb2","bb3");
	bb = b;
	cout << "bb.a:" << bb.a << endl;
	cout << "bb.b:" << bb.b << endl;
	cout << "bb.c.c:" << bb.c.c << endl;

    return 0;
}

运行结果为;

执行结果

当子类和内嵌子对象类都自实现赋值运算符重载函数的时候,不会调用内嵌子对象类的赋值运算符重载函数。

内嵌子对象显式调用

#include <iostream>

using namespace std;


class C
{
public:
	C(string z = "0")
	{
		c = z;
		cout << "C()" << endl;
	}
	C & operator=(const C& another)
	{
		this->c = another.c;
		cout << "C & operator=(const C & another)" << endl;
		return *(this);
	}
	string c;
};





class A
{
public:
	A(string x = " ")
	{
		a = x;
		cout << "A()" << endl;
	}
	A& operator=(const A& another)
	{
		this->a = another.a;
		cout << "A & operator=(const A & another)" << endl;
		return *(this);
	}
	string a;
};

class B:public A
{
public:
	B(string x , string y, string z)
		:A(x),c(z)
	{
		b = y;
		cout << "B()" << endl;
	}

	B & operator=(const B& another)
	{
		if (this == &another)      //判断是否是自赋值
			return *this;
		cout << "B & operator=(const B & another)" << endl;
		A::operator=(another);     //继承父类赋值运算符重载函数
		c = another.c;             //继承内嵌类赋值运算符重载函数
		this->b = another.b;
		return *this;
	}
	C c;
	string b;
};

int main()
{
	B b("b1","b2","b3");
	B bb("bb1","bb2","bb3");
	bb = b;
	cout << "bb.a:" << bb.a << endl;
	cout << "bb.b:" << bb.b << endl;
	cout << "bb.c.c:" << bb.c.c << endl;

    return 0;
}

执行结果为:

执行结果

实战操作

实战:使用系统默认的赋值运算符重载函数实现派生类的赋值。

#include <iostream>
using namespace std;
class Student
{
public:
	Student(string name, int num, char sex)
		:_name(name), _num(num), _sex(sex) {}
	Student(const Student& another)
	{
		_name = another._name;
		_num = another._num;
		_sex = another._sex;
	}
	Student& operator=(const Student& another)
	{
		if (this == &another)
			return *this;
		_name = another._name;
		_num = another._num;
		_sex = another._sex;
	}
	void dump()
	{
		cout << "name:" << _name << endl;
		cout << "num :" << _num << endl;
		cout << "sex :" << _sex << endl;
	}
private:
	string _name;
	int _num;
	char _sex;
};
class Birthday
{
public:
	Birthday(int y, int m, int d)
		:_year(y), _month(m), _day(d)
	{
	}
	Birthday(const Birthday& b)
	{
		_year = b._year;
		_month = b._month;
		_day = b._month;
	}
	void disBirthday()
	{
		cout << "birth date:" << _year << ":" << _month << ":" << _day << endl;
	}
private:
	int _year;
	int _month;
	int _day;
};
class Graduate :public Student
{
public:
	Graduate(string name, int num, char sex, float salary, int y, int m, int d)
		:Student(name, num, sex), _salary(salary), birth(y, m, d)
	{
		_salary = salary;
	}
	Graduate(const Graduate& another)
		:Student(another), birth(another.birth)
	{
		_salary = another._salary;
	}
	void dis()
	{
		dump();
		cout << "salary:" << _salary << endl;
		birth.disBirthday();
	}
private:
	float _salary;
	Birthday birth;
};

int main()
{
	Graduate g("sun", 2001, 's', 10000, 1990, 9, 19);
	g.dis();
	Graduate gg("wang", 2002, 'c', 20000, 3990, 39, 39);
	g = gg;
	g.dis();
	return 0;
}

执行结果为:

执行结果

实战:自实现显式调用赋值运算符重载函数实现派生类的赋值。

#include <iostream>
using namespace std;
class Student
{
public:
	Student(string name, int num, char sex)
		:_name(name), _num(num), _sex(sex) {}
	Student(const Student& another)
	{
		_name = another._name;
		_num = another._num;
		_sex = another._sex;
	}
	Student& operator=(const Student& another)
	{
		if (this == &another)
			return *this;
		_name = another._name;
		_num = another._num;
		_sex = another._sex;
	}
	void dump()
	{
		cout << "name:" << _name << endl;
		cout << "num :" << _num << endl;
		cout << "sex :" << _sex << endl;
	}
private:
	string _name;
	int _num;
	char _sex;
};
class Birthday
{
public:
	Birthday(int y, int m, int d)
		:_year(y), _month(m), _day(d)
	{
	}
	Birthday(const Birthday& b)
	{
		_year = b._year;
		_month = b._month;
		_day = b._month;
	}
	void disBirthday()
	{
		cout << "birth date:" << _year << ":" << _month << ":" << _day << endl;
	}
private:
	int _year;
	int _month;
	int _day;
};
class Graduate :public Student
{
public:
	Graduate(string name, int num, char sex, float salary, int y, int m, int d)
		:Student(name, num, sex), _salary(salary), birth(y, m, d)
	{
		_salary = salary;
	}
	Graduate(const Graduate& another)
		:Student(another), birth(another.birth)
	{
		_salary = another._salary;
	}
	Graduate& operator=(Graduate& another)
	{
		if (this == &another)
			return *this;
		Student::operator =(another);
		birth = another.birth;
		this->_salary = another._salary;
		return *this;
	}
	void dis()
	{
		dump();
		cout << "salary:" << _salary << endl;
		birth.disBirthday();
	}
private:
	float _salary;
	Birthday birth;
};

int main()
{
	Graduate g("sun", 2001, 's', 10000, 1990, 9, 19);
	g.dis();
	Graduate gg("wang", 2002, 'c', 20000, 3990, 39, 39);
	g = gg;
	g.dis();
	return 0;
}

运行结果为:

执行结果

发布了180 篇原创文章 · 获赞 97 · 访问量 1万+

猜你喜欢

转载自blog.csdn.net/qq_43648751/article/details/104895488