子类的拷贝构造 与 赋值重载

1.子类中如果自实现了拷贝构造函数、运算符重载,则需要显式手动调用父类中的对应函数

2.如果子类的拷贝构造和运算符重载,没有调用父类中的对应函数,则在编译时拷贝构造的会报错,而运算符重载的不会报错,但会导致赋值错误

主函数:

#include "stdafx.h"
#include <iostream>
using namespace std;
#include "Student.h"
#include "Graduate.h"


#if 0

//拷贝构造
子类::子类(const 子类& another)
	:父类(another),子类新成员(another.新成员)
{

}

//赋值重载
子类& 子类::operator=(const 子类& another)
{
	if (this == &another)
		return *this; //防止自赋值
	父类::operator =(another); // 调用父类的赋值运算符重载
	this->salary = another.salary;//子类成员初始化
	return *this;
}

#endif



int _tmain(int argc, _TCHAR* argv[])
{
	Student s("zhaosi", 34, 150);
	s.dis();

	cout << "==============================" << endl;

	Graduate g("liuneng", 40, 200, 2000);
	g.print();

	cout << "==============================" << endl;

	Graduate gg(g);
	gg.print();

	cout << "==============================" << endl;

	Graduate ggg("sfsfsf",1,1,1);
	ggg.print();
	ggg = g;
	gg.print();

	return 0;
}

拷贝构造结论:
子类中的默认拷贝构造器会调用父类中默认或自实现拷贝构造器,
若子类中自实现拷贝构造器,则必须显示的调用父类的拷贝构造器


赋值重载结论:
子类的默认赋值运算符重载函数,会调用父类的默认或自实现函数。
子类若自实现,则不会发生默认调用行为,自实现需要手动的调用。
如果没有手动的调用则会导致赋值错误,但编译器不会报错

 

Student.h

#pragma once
#include <iostream>
using namespace std;
#include <string>

class Student
{
public:
	Student(string sn, int ia, float fs);

	Student(const Student &another);

	Student& operator=(const Student& another);

	void dis();

private:
	string name;
	int age;
	float score;

};

 

Student.cpp

#include "Student.h"


Student::Student(string sn, int ia, float fs)
	:name(sn), age(ia), score(fs){}


Student::Student(const Student &another)
{
	//浅拷贝 等位拷贝
	this->name = another.name;
	this->age = another.age;
	this->score = another.score;
}


Student& Student::operator=(const Student& another)
{
	if (this == &another)
		return *this;
	this->name = another.name;
	this->age = another.age;
	this->score = another.score;
	return *this;
}


void Student::dis()
{
	cout << "name: " << name << endl;
	cout << "age: " << age << endl;
	cout << "score: " << score << endl;
}

 

Graduate.h

#pragma once
#include "Student.h"


class Graduate :public Student
{
public:
	Graduate(string sn,int ia,float fs,double ds);
	
	Graduate(const Graduate&another);

	Graduate& operator=(const Graduate&another);

	void print(); //父类中的void dis();也被继承

private:
	double salary;
};

 

Graduate.cpp

#include "Graduate.h"


Graduate::Graduate(string sn, int ia, float fs, double ds)
	:Student(sn, ia, fs), salary(ds){}


//子类未实现拷贝构造时,会调用父类的拷贝构造器(无论实现或未实现)
//子类一旦实现拷贝构造,则必须显示的调用父类的拷贝构造器

Graduate::Graduate(const Graduate&another) //another包含name age score salary
	:Student(another),salary(another.salary) //this->salary(another.salary)
	//只能调用父类的拷贝构造器(因为拷贝构造不能被继承)
	//此处不能用this指针 此处初始化在this指针创建之前,也就是创建对象之前 因此效率高
{
	//赋值兼容(子类对象(引用或指针),可以赋给父类对象(引用或指针)) another赋给父类拷贝构造
	//this->salary=another.salary;
}



//子类中未实现赋值重载时,会调用父类的赋值重载(无论实现或未实现)
//子类一旦实现赋值重载,不会主动调用父类的赋值重载		

Graduate& Graduate::operator=(const Graduate&another)
{
	if (this == &another)
		return *this; 

	Student::operator=(another); //赋值重载函数 可以继承下来 直接调用父类的函数
	
	this->salary = another.salary;

	return *this;
}


void Graduate::print()
{
	dis();
	cout << "salary: " << salary << endl;
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值