ICode9

精准搜索请尝试: 精确搜索
首页 > 编程语言> 文章详细

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

2020-03-16 12:05:13  阅读:290  来源: 互联网

标签:zo cout 子类 C++ 运算符 another 重载 赋值


派生类的赋值符重载

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

情况分析

父类和子类都是系统默认

#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;
}

运行结果为:

执行结果

标签:zo,cout,子类,C++,运算符,another,重载,赋值
来源: https://blog.csdn.net/qq_43648751/article/details/104895488

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有