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