0
点赞
收藏
分享

微信扫一扫

派生类的赋值运算符重载【C++继承】

派生类的赋值符重载

赋值运算符函数,不是构造器,可以看作普通函数去继承。

情况分析

父类和子类都使用系统默认提供的赋值运算符重载

代码演示:

#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)
	{
		if (this == &another)      //判断是否是自赋值
			return *this;
		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;
		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)
	{
		if (this == &another)      //判断是否是自赋值
			return *this;
		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)
	{
		if (this == &another)      //判断是否是自赋值
			return *this;
		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)
	{
		if (this == &another)      //判断是否是自赋值
			return *this;
		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)
	{
		if (this == &another)      //判断是否是自赋值
			return *this;
		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;
	}
	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)
	{
		if (this == &another)      //判断是否是自赋值
			return *this;
		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)
	{
		if (this == &another)      //判断是否是自赋值
			return *this;
		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;
	}

	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;
		this->_name = another._name;
		this->_num = another._num;
		this->_sex = another._sex;
		return *this;
	}

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

	Birthday & operator=(const Birthday & another)
	{
		if (this == &another)
			return *this;
		this->_year = another._year;
		this->_month = another._month;
		this->_day = another._month;
		return *this;
	}

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

运行结果:

执行结果

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

代码演示:

#define _CRT_SECURE_NO_WARNINGS
#include <iostream>


using namespace std;

class Student
{
public:
	Student(string name, int num, char sex)
		:_name(name), _num(num), _sex(sex)
	{
		strS = new char[13]{ "helloworld_S" };
	}

	Student(const Student& another)
	{
		_name = another._name;
		_num = another._num;
		_sex = another._sex;

	}

	Student& operator=(const Student& another)
	{
		if (this == &another)
			return *this;
		this->_name = another._name;
		this->_num = another._num;
		this->_sex = another._sex;

		delete[] strS;
		this->strS = new char[strlen(another.strS) + 1];
		strcpy(this->strS,another.strS);
		return *this;
	}

	void dump()
	{
		cout << "name:" << _name << endl;
		cout << "num :" << _num << endl;
		cout << "sex :" << _sex << endl;
		cout << "strS :" << strS << endl;
	}
private:
	string _name;
	int _num;
	char _sex;
	char* strS;
};

class Birthday
{
public:
	Birthday(int y, int m, int d)
		:_year(y), _month(m), _day(d)
	{
		strB = new char[13]{ "helloworld_B" };
	}

	Birthday(const Birthday& b)
	{
		_year = b._year;
		_month = b._month;
		_day = b._month;
	}

	Birthday& operator=(const Birthday& another)
	{
		if (this == &another)
			return *this;
		this->_year = another._year;
		this->_month = another._month;
		this->_day = another._month;

		delete[] this->strB;
		this->strB = new char[strlen(another.strB) + 1];
		strcpy(this->strB, another.strB);

		return *this;
	}

	void disBirthday()
	{
		cout << "birth date:" << _year
			<< ":" << _month << ":" << _day << endl;
		cout << "strB :" << strB << endl;
	}
private:
	int _year;
	int _month;
	int _day;
	char* strB;
};

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;
		strG = new char[15]{ "helloworld_G" };
	}

	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;

		delete[] strG;
		strG = new char[strlen(another.strG) + 1];
		strcpy(this->strG, another.strG);
		return *this;
	}
	void dis()
	{
		dump();
		cout << "salary:" << _salary << endl;
		cout << "strG :" << strG << endl;
		birth.disBirthday();
	}
private:
	float _salary;
	Birthday birth;
	char* strG;
};

int main()
{
	Graduate g("sun", 2001, 's', 10000, 1990, 9, 19);
	g.dis();

	cout << "\n**********************************\n" << endl;

	Graduate gg("wang", 2002, 'c', 20000, 3990, 39, 39);
	g = gg;
	g.dis();
	return 0;
}

运行结果:
运行结果

举报

相关推荐

0 条评论