18 C++11 类初始化, explicit,构造函数初始化列表,const,liline,mutable,this指针,static,=defaule,=delete,拷贝构造函数,赋值拷贝,继承

一 类的初始化

类的初始化有如下的模式

    Teacher5 tea1; //无参数构造函数
    Teacher5 tea7{};//无参数构造函数
    cout << "111" << endl;
    //Teacher5 tea8(); //这不会调用构造函数

    Teacher5 tea2(23,(char *)"nihao");//有参数的构造函数被调用
    Teacher5 tea3{33,(char*)"33nihao33"};//有参数的构造函数被调用
    Teacher5 tea4 = Teacher5(43,(char *)"43nihao43");//有参数的构造函数被调用
    Teacher5 tea5 = Teacher5{ 53, (char *)"53nihao53" };//有参数的构造函数被调用
 

teacher5.h

teacher5.h

#ifndef _HEADTEACHER5_H_
#define _HEADTEACHER5_H_

#include 
using namespace std;

class Teacher5 {

public:
	//构造函数声明
	Teacher5();
	Teacher5(int age,char name[64]);

private:
	int _age;
	char _name[64];

public:
	void printTeacher5();
};

#endif

teacher5.cpp

#include "teacher5.h"

//构造函数定义
Teacher5::Teacher5()
{
	cout << "Teacher5 没有参数的构造函数调用" << endl;
}

Teacher5::Teacher5(int age, char name[64]) {
	this->_age = age;
	memset(this->_name, 0, sizeof(this->_name));
	strcpy_s(this->_name,sizeof(this->_name) ,name);
	cout << "Teacher5 int age, char name[64] 的构造函数调用" << endl;
}

void Teacher5::printTeacher5() {
	cout << "address = " << this << " age = " << this->_age << " name = " << this->_name << endl;
}

main.cpp

main.cpp

#include "teacher5.h"
//类的初始化,参考teacher5.h 和 teacher5.cpp
void main() {
	Teacher5 tea1; //无参数构造函数
	Teacher5 tea7{};//无参数构造函数
	cout << "111" << endl;
	//Teacher5 tea8(); //这不会调用构造函数

	Teacher5 tea2(23,(char *)"nihao");//有参数的构造函数被调用
	Teacher5 tea3{33,(char*)"33nihao33"};//有参数的构造函数被调用
	Teacher5 tea4 = Teacher5(43,(char *)"43nihao43");//有参数的构造函数被调用
	Teacher5 tea5 = Teacher5{ 53, (char *)"53nihao53" };//有参数的构造函数被调用

	tea2.printTeacher5();
	tea3.printTeacher5();
	tea4.printTeacher5();
	tea5.printTeacher5();
	cout << "断点在这里" << endl;
}

二 函数的默认参数

//函数可以有默认参数,一旦一个参数是默认参数,
    //那么它右边的所有参数都必须是默认参数.
    // 默认参数的声明需要写在teacher6.h中,
    //Teacher6(int age, double score = 100);
    //但是默认参数的定义中不用写默认参数的值
    //Teacher6::Teacher6(int age, double score) {}

teacher6.h

#ifndef _HEADTEACHER6_H_
#define _HEADTEACHER6_H_

#include 
using namespace std;

class Teacher6 {

public:
	//构造函数声明
	Teacher6();

	Teacher6(int age,char name[64]);

	//函数可以有默认参数,一旦一个参数是默认参数,那么它右边的所有参数都必须是默认参数
	Teacher6(int age, double score = 100);
private:
	int _age;
	char _name[64];
	double _score;

public:
	void printTeacher6();
};

#endif

teacher6.cpp

#include "teacher6.h"

//构造函数定义
Teacher6::Teacher6()
{
	cout << "Teacher6 没有参数的构造函数调用" << endl;
}

Teacher6::Teacher6(int age, char name[64]) {
	this->_age = age;
	memset(this->_name, 0, sizeof(this->_name));
	strcpy_s(this->_name,sizeof(this->_name) ,name);
	cout << "Teacher6 int age, char name[64] 的构造函数调用" << endl;
}

//默认参数的定义中不用写默认参数的值
Teacher6::Teacher6(int age, double score) {
	cout << "Teacher6 int age, double score 的构造函数调用" << endl;
	this->_age = age;
	this->_score = score;
}

void Teacher6::printTeacher6() {
	cout << "address = " << this << " age = " << this->_age 
		<< " name = " << this->_name 
		<< " score = " << this->_score 
		<< endl;
}

main.cpp

#include "teacher6.h"
//二 函数的默认参数
void main() {
	Teacher6 tea1;
	tea1.printTeacher6();

	//函数可以有默认参数,一旦一个参数是默认参数,
	//那么它右边的所有参数都必须是默认参数.
	// 默认参数的声明需要写在teacher6.h中,
	//Teacher6(int age, double score = 100);
	//但是默认参数的定义中不用写默认参数的值
	//Teacher6::Teacher6(int age, double score) {}
	Teacher6 tea2(18);
	tea2.printTeacher6();//打印值为 age =18,score = 100

	Teacher6 tea3(28, 88.8);
	tea3.printTeacher6();//打印值为 age =28,score = 88.8
}

三。类内初始化。如果没有给age赋值,则默认是99

teacher 7.h

#ifndef _HEADTEACHER7_H_
#define _HEADTEACHER7_H_

#include 
using namespace std;

class Teacher7 {

public:
	//构造函数声明
	Teacher7();

	Teacher7(int age,char name[64]);

	//函数可以有默认参数,一旦一个参数是默认参数,那么它右边的所有参数都必须是默认参数
	Teacher7(int age, double score = 100);
private:
	int _age = 99;//3. 类内初始化。如果没有给age赋值,则默认是99
	char _name[64];
	double _score;

public:
	void printTeacher7();
};

#endif

teacher7.cpp

#include "teacher7.h"

//构造函数定义
Teacher7::Teacher7()
{
	cout << "Teacher7 没有参数的构造函数调用" << endl;
}

Teacher7::Teacher7(int age, char name[64]) {
	this->_age = age;
	memset(this->_name, 0, sizeof(this->_name));
	strcpy_s(this->_name,sizeof(this->_name) ,name);
	cout << "Teacher7 int age, char name[64] 的构造函数调用" << endl;
}

Teacher7::Teacher7(int age, double score) {
	cout << "Teacher7 int age, double score 的构造函数调用" << endl;
	this->_age = age;
	this->_score = score;
}

void Teacher7::printTeacher7() {
	cout << "address = " << this << " age = " << this->_age 
		<< " name = " << this->_name 
		<< " score = " << this->_score 
		<< endl;
}

main.cpp

///三。类内的初始值,参考teacher7.h 和 teacher7.cpp
#include "teacher7.h"
void main() {
	Teacher7 tea1;
	tea1.printTeacher7();//打印值为 age =99,其他值为乱码
}

四 explicit 关键字:明确的定义,为什么要让这个关键字呢?

teacher8.h

#ifndef _HEADTEACHER8_H_
#define _HEADTEACHER8_H_

#include 
using namespace std;

class Teacher8 {

public:
	Teacher8();

	//Teacher8(int age);

	explicit Teacher8(int age);

private:
	int _age = 99;
	char _name[64];
	double _score;

public:
	void printTeacher8();
};

#endif

teacher8.cpp

#include "teacher8.h"

//构造函数定义
Teacher8::Teacher8()
{
	cout << "Teacher8 没有参数的构造函数调用" << endl;
}

Teacher8::Teacher8(int age) {
	this->_age = age;
	cout << "Teacher8 int age, char name[64] 的构造函数调用" << endl;
}


void Teacher8::printTeacher8() {
	cout << "address = " << this << " age = " << this->_age 
		<< " name = " << this->_name 
		<< " score = " << this->_score 
		<< endl;
}

main.cpp

#include "teacher8.h"
//四 explicit 关键字:明确的定义,为什么要让这个关键字呢?参考teacher8.h 和 teacher8.cpp
//explicit 只适用于一个参数的构造函数

void main() {
	//当有一个参数的构造函数前面没有加 explicit时,如下的写法都行,但是会引起歧义。
	Teacher8 tea1 = 9;//在有一个参数的构造函数前面没有加 explicit时,这种写法,会将age的值变成9,虽然是可以的,但是不好理解。
	tea1.printTeacher8(); //结果为 打印出来age = 9;

	Teacher8 tea2 = (19,29,39);//这种写法也可以,会将逗号表达的值做为参数传递给age
	tea2.printTeacher8(); //结果为 打印出来age = 39;

	//如上的这些写法为啥可以呢?实际上C++编译器都是做了临时对象或者隐式转换的一些操作。
	//这就很不好了,不仅让代码显得很难懂,也很2.
	//于是在C++ 11 中,发明了 explicit关键字。 explicit的意思是明确的,告诉C++编译器不要给我隐式转换。

	//当我们将有一个参数的 构造函数 声明成 explicit的后,
	//则如上的写法都会有build error,error 信息为: 无法从“int”转换为“Teacher8”	001for	d : \allinformation\cpp\001for\001for\001for\001for.cpp	18
	//Teacher8 tea3 = 9;//build error 无法从“int”转换为“Teacher8”
	//Teacher8 tea4 = (19, 29, 39);//build error 无法从“int”转换为“Teacher8”
}

五 构造函数初始化成员列表 

在函数体之前就 做了函数成员的初始化,初始化顺序和 变量定义的顺序一样。这样说,更加精确 。注意是 和在 .h中变量声明的顺序一样

格式:并建议这么干

Teacher9::Teacher9(int age, string name, double score) :_age(age), _name(name), _score(score) {
    cout << "Teacher9 int age, char name[64],double score 的构造函数调用" << endl;
}

const 成员变量的初始化,只能使用初始化成员列表

正常对于传递进去的参数

teacher9.h

#ifndef _HEADTEACHER9_H_
#define _HEADTEACHER9_H_

#include 
#include 
using namespace std;

class Teacher9 {

public:
	Teacher9();

	Teacher9(int age);

	Teacher9(int age,char *name);

	Teacher9(int age,char *name,double score);


private:
	int _age = 99;
	char _name[64];
	double _score;

public:
	void printTeacher9();
};

#endif

teacher9.cpp

#include "teacher9.h"

//构造函数定义
Teacher9::Teacher9()
{
	cout << "Teacher9 没有参数的构造函数调用" << endl;
}

Teacher9::Teacher9(int age) {
	this->_age = age;
	cout << "Teacher9 int age,的构造函数调用" << endl;
}

Teacher9::Teacher9(int age, char *name) {

	this->_age = age;
	memset(this->_name, 0,sizeof(this->_name));
	strcpy_s(this->_name,sizeof(this->_name),name);
	cout << "Teacher9 int age, char name[64] 的构造函数调用" << endl;
}

Teacher9::Teacher9(int age, char *name, double score) {
	this->_age = age;
	memset(this->_name, 0, sizeof(this->_name));
	strcpy_s(this->_name, sizeof(this->_name), name);
	this->_score = score;
	cout << "Teacher9 int age, char name[64],double score 的构造函数调用" << endl;
}

void Teacher9::printTeacher9() {
	cout << "address = " << this << " age = " << this->_age 
		<< " name = " << this->_name 
		<< " score = " << this->_score 
		<< endl;
}

main.cpp

#include "teacher9.h"

void main() {
	Teacher9 tea1;
	tea1.printTeacher9();

	Teacher9  tea2(100);
	tea2.printTeacher9();

	Teacher9 tea3(200, (char *)"tea3");
	tea3.printTeacher9();

	Teacher9 tea4(300, (char *)"tea4",99.9);
	tea4.printTeacher9();
}




构造函数初始化列表

teacher9.h

#ifndef _HEADTEACHER9_H_
#define _HEADTEACHER9_H_

#include 
#include 
using namespace std;

class Teacher9 {

public:
	Teacher9();

	Teacher9(int age);

	Teacher9(int age,string name);

	Teacher9(int age, string name,double score);


private:
	int _age = 99;
	string _name; //如果要使用函数初始化列表,对于char name[64],无法做函数初始化列表,请使用C++的string
	double _score;

public:
	void printTeacher9();
};

#endif

teacher9.cpp

#include "teacher9.h"

//构造函数定义
Teacher9::Teacher9()
{
	cout << "Teacher9 没有参数的构造函数调用" << endl;
}

Teacher9::Teacher9(int age):_age(age) {
	cout << "Teacher9 int age,的构造函数调用" << endl;
}

//注意,这里如果是 c 字符串的char [], 无法使用 构造函数初始化列表参数
//Teacher9::Teacher9(int age, char *name) :_age(age),_name(name){//这里有build error,
//那么如果是char [],怎么弄呢?请使用string
Teacher9::Teacher9(int age, string name):_age(age),_name(name) {
	cout << "Teacher9 int age, char name[64] 的构造函数调用" << endl;
}

Teacher9::Teacher9(int age, string name, double score) :_age(age), _name(name), _score(score) {
	cout << "Teacher9 int age, char name[64],double score 的构造函数调用" << endl;
}

void Teacher9::printTeacher9() {
	cout << "address = " << this << " age = " << this->_age 
		<< " name = " << this->_name 
		<< " score = " << this->_score 
		<< endl;
}

main.cpp

//五 构造函数初始化列表 参考 teacher9.h 和 teacher9.cpp
#include "teacher9.h"

void main() {
	Teacher9 tea1;
	tea1.printTeacher9();

	Teacher9  tea2(100);
	tea2.printTeacher9();

	Teacher9 tea3(200, "tea3");
	tea3.printTeacher9();

	Teacher9 tea4(300, "tea4",99.9);
	tea4.printTeacher9();
}

六,类中成员函数是inline,则要在teacher.h中函数定义,而不仅仅是函数声明

teacher10.h

#ifndef _HEADTEACHER10_H_
#define _HEADTEACHER10_H_

#include 
#include 
using namespace std;

class Teacher10 {

public:
	Teacher10();

	Teacher10(int age);

	Teacher10(int age,string name);

	Teacher10(int age, string name,double score);


private:
	int _age = 99;
	string _name;
	double _score;

public:
	void printTeacher10();

public:
	// inline :内联函数,需要写在 teacher.h中,这是因为C++编译器会将 内联函数 换成 函数体。
	//而我们在main.cpp中使用的使用是include "teacher.h"的,并没有引用"teacher.cpp"中,
	//因此如果我们写在teacher.h中,那么当替换的时候,只能找到addTeacher()方法的声明,看不到 函数体,就会有build error
	inline void addTeacher10() {
		cout << " age + socre = " << this->_age + this->_score << endl;
	}
};

#endif

teacher10.cpp

#include "teacher10.h"

//构造函数定义
Teacher10::Teacher10()
{
	cout << "Teacher10 没有参数的构造函数调用" << endl;
}

Teacher10::Teacher10(int age):_age(age) {
	cout << "Teacher10 int age,的构造函数调用" << endl;
}

//注意,这里如果是 c 字符串的char [], 无法使用 构造函数初始化列表参数
//Teacher9::Teacher9(int age, char *name) :_age(age),_name(name){//这里有build error,
//那么如果是char [],怎么弄呢?请使用string
Teacher10::Teacher10(int age, string name):_age(age),_name(name) {
	cout << "Teacher10 int age, char name[64] 的构造函数调用" << endl;
}

Teacher10::Teacher10(int age, string name, double score) :_age(age), _name(name), _score(score) {
	cout << "Teacher10 int age, char name[64],double score 的构造函数调用" << endl;
}

void Teacher10::printTeacher10() {
	cout << "address = " << this << " age = " << this->_age 
		<< " name = " << this->_name 
		<< " score = " << this->_score 
		<< endl;
}

main.cpp

//六 构造函数中使用inLine
//inLine:编译器会将inLine函数换成函数体
//一般情况下,成员函数的声明,会放在teacher.h中
//            成员函数的定义,会放在teacher.cpp中
//但是如果是inLine的成员函数,成员函数的定义会放在 teacher.h中
	// inline :内联函数,需要写在 teacher.h中,这是因为C++编译器会将 内联函数 换成 函数体。
	//而我们在main.cpp中使用的使用是include "teacher.h"的,并没有引用"teacher.cpp"中,
	//因此如果我们写在teacher.h中,那么当替换的时候,只能找到addTeacher()方法的声明,看不到 函数体,就会有build error
#include "teacher10.h"

void main() {
	Teacher10 tea1(100, "nihao", 99.88);
	tea1.printTeacher10();
	tea1.addTeacher10();
}

七. 类中成员函数是const

//七 成员函数中有const 参考teacher11.h teacher11.cpp 
//1.const要加在成员函数的后面。
//2.const在 成员函数声明 时要写
//3.const在 成员函数定义 时也要写
//4.表示在该函数中不能改动 成员变量的值

//5.定义的对象如果是const ,则只能调用 const 函数。

// 6.定义的对象如果不是const,也可以调用const 函数,

teacher11.h

#ifndef _HEADTEACHER11_H_
#define _HEADTEACHER11_H_

#include 
#include 
using namespace std;

class Teacher11 {

public:
	Teacher11();

	Teacher11(int age);

	Teacher11(int age,string name);

	Teacher11(int age, string name,double score);

private:
	int _age = 99;
	string _name;
	double _score;

public:
	void printTeacher11();

public:
	// inline :内联函数,需要写在 teacher.h中,这是因为C++编译器会将 内联函数 换成 函数体。
	//而我们在main.cpp中使用的使用是include "teacher.h"的,并没有引用"teacher.cpp"中,
	//因此如果我们写在teacher.h中,那么当替换的时候,只能找到addTeacher()方法的声明,看不到 函数体,就会有build error
	inline void addTeacher11() {
		cout << " age + socre = " << this->_age + this->_score << endl;
	}

	//const 要加在成员函数后面,表示在该函数中不能改动 成员变量的值
	void subTeacher11() const;

	//const 加在成员函数前面,则不起作用,该函数中依然能改动 成员变量的值
	const void subTeacher12() ;
};

#endif

teacher11.cpp

#include "teacher11.h"

//构造函数定义
Teacher11::Teacher11()
{
	cout << "Teacher11 没有参数的构造函数调用" << endl;
}

Teacher11::Teacher11(int age):_age(age) {
	cout << "Teacher11 int age,的构造函数调用" << endl;
}

//注意,这里如果是 c 字符串的char [], 无法使用 构造函数初始化列表参数
//Teacher9::Teacher9(int age, char *name) :_age(age),_name(name){//这里有build error,
//那么如果是char [],怎么弄呢?请使用string
Teacher11::Teacher11(int age, string name):_age(age),_name(name) {
	cout << "Teacher11 int age, char name[64] 的构造函数调用" << endl;
}

Teacher11::Teacher11(int age, string name, double score) :_age(age), _name(name), _score(score) {
	cout << "Teacher11 int age, char name[64],double score 的构造函数调用" << endl;
}

void Teacher11::printTeacher11() {
	cout << "address = " << this << " age = " << this->_age 
		<< " name = " << this->_name 
		<< " score = " << this->_score 
		<< endl;
}

//const 要加在成员函数后面,表示在该函数中不能改动 成员变量的值
void Teacher11::subTeacher11() const {
	cout << " subTeacher11 const 后面 " << " age - score = " << _age - _score << endl;
	//_age = _age++;//const 修饰的函数表示不能改动 成员变量
	//this->_score = 90.0;
}

//const 加在成员函数前面,则不起作用,该函数中依然能改动 成员变量的值
const void Teacher11::subTeacher12() {
	_age = _age++;//const 修饰的函数表示不能改动 成员变量
	this->_score = 90.0;
	cout << "const 前面 subTeacher12  " << " age - score = " << _age - _score << endl;
}

main.cpp

//七 成员函数中有const 参考teacher11.h teacher11.cpp 
//1.const要加在成员函数的后面。
//2.const在 成员函数声明 时要写
//3.const在 成员函数定义 时也要写
//4.表示在该函数中不能改动 成员变量的值
//5.定义的对象如果是const ,则只能调用 const 函数。
//6.定义的对象如果不是const,也可以调用const 函数,
#include "teacher11.h"

void main() {
	Teacher11 tea1(100, "nihao", 8.8);
	tea1.subTeacher11();
	tea1.subTeacher12();
	tea1.printTeacher11();
	//5.定义的对象如果是const ,则只能调用 const 函数。
	const Teacher11 tea6;
	//tea6.printTeacher11();//build error
	//tea6.addTeacher11();//build error
	tea6.subTeacher11();//只能调用 const 函数
	//tea6.subTeacher12();//build error

	// 6.定义的对象如果不是const,也可以调用const 函数,
	Teacher11  tea7;
	tea7.printTeacher11();//ok
	tea7.addTeacher11();//ok
	tea7.subTeacher11();//调用const 函数也是ok的
	tea7.subTeacher12();//ok
}

//运行结果
Teacher11 int age, char name[64],double score 的构造函数调用
 subTeacher11 const 后面  age - score = 91.2
const 前面 subTeacher12   age - score = 11
address = 00000085737DFC38 age = 101 name = nihao score = 90

八 类中成员变量是 mutable

//八 mutable (不容易,不稳定)修饰成员变量,用于const 的反义词。
//如果该成员变量被 mutable 修饰,表示即使函数是const ,也可以改动该值

teacher12.h

#ifndef _HEADTEACHER12_H_
#define _HEADTEACHER12_H_

#include 
#include 
using namespace std;

class Teacher12 {

public:
	Teacher12();

	Teacher12(int age);

	Teacher12(int age,string name);

	Teacher12(int age, string name,double score);


	Teacher12(int age, string name, double score,int number);

private:
	int _age = 99;
	string _name;
	double _score;
	mutable int _number;八 mutable (不容易,不稳定)修饰成员变量,用于const 的反义词。
//如果该成员变量被 mutable 修饰,表示即使函数是const ,也可以改动该值

public:
	void printTeacher12();

public:
	// inline :内联函数,需要写在 teacher.h中,这是因为C++编译器会将 内联函数 换成 函数体。
	//而我们在main.cpp中使用的使用是include "teacher.h"的,并没有引用"teacher.cpp"中,
	//因此如果我们写在teacher.h中,那么当替换的时候,只能找到addTeacher()方法的声明,看不到 函数体,就会有build error
	inline void addTeacher12() {
		cout << " age + socre = " << this->_age + this->_score << endl;
	}

	//const 要加在成员函数后面,表示在该函数中不能改动 成员变量的值
	void subTeacher12() const;


};

#endif

teacher12.cpp

#include "teacher12.h"

//构造函数定义
Teacher12::Teacher12()
{
	cout << "Teacher12 没有参数的构造函数调用" << endl;
}

Teacher12::Teacher12(int age):_age(age) {
	cout << "Teacher12 int age,的构造函数调用" << endl;
}

//注意,这里如果是 c 字符串的char [], 无法使用 构造函数初始化列表参数
//Teacher9::Teacher9(int age, char *name) :_age(age),_name(name){//这里有build error,
//那么如果是char [],怎么弄呢?请使用string
Teacher12::Teacher12(int age, string name):_age(age),_name(name) {
	cout << "Teacher12 int age, char name[64] 的构造函数调用" << endl;
}

Teacher12::Teacher12(int age, string name, double score) :_age(age), _name(name), _score(score) {
	cout << "Teacher12 int age, char name[64],double score 的构造函数调用" << endl;
}

Teacher12::Teacher12(int age, string name, double score, int number):_age(age),_name(name),_score(score),_number(number) {
	cout << "Teacher12 int age, char name[64],double score,int number 的构造函数调用" << endl;
}
void Teacher12::printTeacher12() {
	cout << "address = " << this << " age = " << this->_age 
		<< " name = " << this->_name 
		<< " score = " << this->_score 
		<< " number = " <_number
		<< endl;
}

//const 要加在成员函数后面,表示在该函数中不能改动 成员变量的值
void Teacher12::subTeacher12() const {
	cout << " subTeacher12 const 后面 " << " age - score = " << _age - _score << endl;
	//this->_age = 88;//const 修饰的函数表示不能改动 成员变量
	//this->_score = 90.0;
	_number = 90;//const 修饰的函数表示不能改动 成员变量,但是如果是 mutable修饰的,则可以改动
}

main.cpp

//八 mutable (不容易,不稳定)修饰成员变量,用于const 的反义词。
//如果该成员变量被 mutable 修饰,表示即使函数是const ,也可以改动该值
//参考teacher12.h  teacher12.cpp
#include "teacher12.h"

void main() {
	Teacher12 tea1;
	tea1.subTeacher12();
	tea1.printTeacher12();
}

九 this 指针

是一个指针,指向自己,实际上C++


//this是一个指针,指向自己。
//如果一个成员函数需要返回自己的引用。指定写法为 return * this

Teacher13(int age);


Teacher13::Teacher13( int age) :_age(age) {
// C++编译器实际上会默认加了一个 this参数,且这个this只能指向自己。因此this要用const修饰。 
//Teacher13::Teacher13(Teacher13* const this, int age) :_age(age) {
	cout << "Teacher13 int age,的构造函数调用" << endl;
	this->_age = age;//注意,this指向的值是可以改动的,不然this->age 就不能改变
}


Teacher13  Teacher13::getTeacher13() {
	this->_age = 90;
	return *this;
}

Teacher13& Teacher13::getTeacheryingyong13() {
	this->_age = 190;
	return *this;
}


//九 this 指针探究//参考teacher13.h  teacher13.cpp
//this是一个指针,指向自己。
//如果一个成员函数需要返回自己的引用。
#include "teacher13.h"

void main() {
	Teacher13  tea1(20,"nihao",99.8,80);
	tea1.printTeacher13();

	//这个getTeacher13返回的是:Teacher13 实例
	Teacher13 tea2 = tea1.getTeacher13();
	tea2.printTeacher13();

	//这个getTeacheryingyong13函数返回的是 : Teacher13的引用
	Teacher13 tea3 = tea1.getTeacheryingyong13();
	tea3.printTeacher13();

}

十 static 类成员变量 和 static 类成员函数

静态成员函数,也是属于类,但是不属于任何成员对象。

静态成员函数不能修改非静态成员。

静态成员定义 和 静态成员的赋值。

#ifndef _HEADTEACHER14_H_
#define _HEADTEACHER14_H_

#include 
#include 
using namespace std;

class Teacher14 {

public:
	//静态成员的声明
	static int staticage;

public:
	//静态方法的声明
	static void changedthestaticage(int value);

public:
	Teacher14();
	Teacher14(int age);
	Teacher14(int age, string name);
	Teacher14(int age, string name, double score);
	Teacher14(int age, string name, double score, int number);

private:
	int _age = 99;
	string _name;
	double _score;
	mutable int _number;八 mutable (不容易,不稳定)修饰成员变量,用于const 的反义词。
//如果该成员变量被 mutable 修饰,表示即使函数是const ,也可以改动该值

public:
	void printTeacher14();
	Teacher14  getTeacher14();
	Teacher14 & getTeacheryingyong14();
public:
	// inline :内联函数,需要写在 teacher.h中,这是因为C++编译器会将 内联函数 换成 函数体。
	//而我们在main.cpp中使用的使用是include "teacher.h"的,并没有引用"teacher.cpp"中,
	//因此如果我们写在teacher.h中,那么当替换的时候,只能找到addTeacher()方法的声明,看不到 函数体,就会有build error
	inline void addTeacher14() {
		cout << " age + socre = " << this->_age + this->_score << endl;
	}
	//const 要加在成员函数后面,表示在该函数中不能改动 成员变量的值
	void subTeacher14() const;
};

#endif

#include "teacher14.h"

//静态方法的定义
void Teacher14::changedthestaticage(int value)
{
	staticage = value;
}

//构造函数定义
Teacher14::Teacher14( )
{
	cout << "Teacher14 没有参数的构造函数调用" << endl;
}

Teacher14::Teacher14( int age) :_age(age) {
// C++编译器实际上会默认加了一个 this参数,且这个this只能指向自己。因此this要用const修饰。 
//Teacher14::Teacher14(Teacher13* const this, int age) :_age(age) {
	cout << "Teacher14 int age,的构造函数调用" << endl;
	this->_age = age;//注意,this指向的值是可以改动的,不然this->age 就不能改变
}

//注意,这里如果是 c 字符串的char [], 无法使用 构造函数初始化列表参数
//Teacher9::Teacher9(int age, char *name) :_age(age),_name(name){//这里有build error,
//那么如果是char [],怎么弄呢?请使用string
Teacher14::Teacher14(int age, string name):_age(age),_name(name) {
	cout << "Teacher14 int age, char name[64] 的构造函数调用" << endl;
}

Teacher14::Teacher14(int age, string name, double score) :_age(age), _name(name), _score(score) {
	cout << "Teacher14 int age, char name[64],double score 的构造函数调用" << endl;
}

Teacher14::Teacher14(int age, string name, double score, int number):_age(age),_name(name),_score(score),_number(number) {
	cout << "Teacher14 int age, char name[64],double score,int number 的构造函数调用" << endl;
}

void Teacher14::printTeacher14() {
	cout << "address = " << this << " age = " << this->_age 
		<< " name = " << this->_name 
		<< " score = " << this->_score 
		<< " number = " <_number
		<< endl;
}

//const 要加在成员函数后面,表示在该函数中不能改动 成员变量的值
void Teacher14::subTeacher14() const {
	cout << " subTeacher13 const 后面 " << " age - score = " << _age - _score << endl;
	//this->_age = 88;//const 修饰的函数表示不能改动 成员变量
	//this->_score = 90.0;
	_number = 90;//const 修饰的函数表示不能改动 成员变量,但是如果是 mutable修饰的,则可以改动
}

Teacher14  Teacher14::getTeacher14() {
	this->_age = 90;
	return *this;
}

Teacher14& Teacher14::getTeacheryingyong14() {
	this->_age = 190;
	return *this;
}

//十 static 静态成员和静态方法
#include "teacher14.h"
//静态 成员变量 的初始化,需要在main方法外初始化

int Teacher14::staticage = 200;
void main() {
	
	//静态成员的使用方法 和 静态方法的使用方法
	cout << Teacher14::staticage << endl;
	Teacher14 tea1;
	tea1.changedthestaticage(300);
	cout << Teacher14::staticage << endl;
	cout << tea1.staticage << endl;
}

十一:=default 和  =delete 关键字

这两都用于无参数的构造函数。

=default  表示C++编译器给无参数的构造方法生成函数体

=delete   表示C++编译器不会给 无参数的构造方法生成函数体

teacher14.h 中声明无参数的构造函数

public:
	Teacher14() = default;


相当于在 teacher14.cpp中,
生成了
Teacher14(){
//啥也没有
}


public:
	Teacher14() = delete;

表示编译器不会自动生成构造方法

十二 拷贝构造函数 和 赋值操作符重载

    //拷贝构造函数 只能有一个,写法如下
    Teacher15(const Teacher15 & teacher);

注意的是:C++编译器默认的 拷贝构造函数是 浅拷贝,假设是一个char * ,那么只会拷贝地址,不会拷贝地址指向的内容,这就有问题了,当释放 tea1和tea2的时候,会发生重复释放这块内存两次的问题,从而导致exception

拷贝构造函数 调用时机

1.在 teacher tea2 = tea1时候。

2.当一个函数的返回值是临时对象时

---------------------------------------------------------

运算符重载,实际上也是 一种函数

两个teacher如何比较呢?要用到重载运算符。

写法: 返回值 operator运算符(参数)

Teacher15& Teacher15::operator=(Teacher15 &teacher) ;

Teacher15& Teacher15::operator=(Teacher15 &teacher) {

}

teacher15.h

#ifndef _HEADTEACHER15_H_
#define _HEADTEACHER15_H_

#include 
#include 
using namespace std;

class Teacher15 {

public:
	//拷贝构造函数
	Teacher15(const Teacher15 & teacher);

	//构造函数
public:
	Teacher15();
	Teacher15(int age);
	Teacher15(int age, string name);
	Teacher15(int age, string name, double score);
	Teacher15(int age, string name, double score, int number);
	Teacher15(int age, string name, char* char_name, 
		char * char_zhizhen_name, double score, int number);

	//析构函数
public:
	~Teacher15();

	//=操作符重写
public:
	Teacher15& operator=(Teacher15 &obj);

private:
	int _age = 99;
	string _name;
	char _char_name[64];
	char* _char_zhizhen_name;
	double _score;
	mutable int _number;八 mutable (不容易,不稳定)修饰成员变量,用于const 的反义词。
//如果该成员变量被 mutable 修饰,表示即使函数是const ,也可以改动该值

public:
	void printTeacher15();

public:
	// inline :内联函数,需要写在 teacher.h中,这是因为C++编译器会将 内联函数 换成 函数体。
	//而我们在main.cpp中使用的使用是include "teacher.h"的,并没有引用"teacher.cpp"中,
	//因此如果我们写在teacher.h中,那么当替换的时候,只能找到addTeacher()方法的声明,看不到 函数体,就会有build error
	inline void addTeacher5() {
		cout << " age + socre = " << this->_age + this->_score << endl;
	}
	//const 要加在成员函数后面,表示在该函数中不能改动 成员变量的值
	void subTeacher15() const;
};

#endif

teacher15.cpp

#include "teacher15.h"

//拷贝构造函数定义
Teacher15::Teacher15(const Teacher15 & teacher)
{
	this->_age = teacher._age;
	this->_score = teacher._score;
	this->_number = teacher._number;
	this->_name = teacher._name;
	//对于 char _char_name[64]
	memset(this->_char_name, 0, sizeof(this->_char_name));
	strcpy_s(this->_char_name,sizeof(this->_char_name),teacher._char_name);

	//对于 char* _char_zhizhen_name 
	int templength = strlen(teacher._char_zhizhen_name) + 1;
	cout << "templength = " << templength<_char_zhizhen_name = new char[templength];
	memset(this->_char_zhizhen_name, 0, templength);
	strcpy_s(this->_char_zhizhen_name, templength, teacher._char_zhizhen_name);
}

//
Teacher15& Teacher15::operator=(Teacher15 &teacher) {
	this->_age = teacher._age;
	this->_score = teacher._score;
	this->_number = teacher._number;
	this->_name = teacher._name;
	//对于 char _char_name[64]
	memset(this->_char_name, 0, sizeof(this->_char_name));
	strcpy_s(this->_char_name, sizeof(this->_char_name), teacher._char_name);

	//对于 char* _char_zhizhen_name 
	int templength = strlen(teacher._char_zhizhen_name) + 1;
	cout << "operator templength = " << templength << endl;
	this->_char_zhizhen_name = new char[templength];
	memset(this->_char_zhizhen_name, 0, templength);
	strcpy_s(this->_char_zhizhen_name, templength, teacher._char_zhizhen_name);
	return *this;
}

//构造函数定义
Teacher15::Teacher15(int age, 
	string name, 
	char* char_name,
	char * char_zhizhen_name, 
	double score, 
	int number):_age(age),_name(name),_score(score),_number(number){


	//1.将 "charname[]" 的值存储到 this->_char_name.
	memset(this->_char_name,0,sizeof(this->_char_name));
	strcpy_s(this->_char_name,sizeof(this->_char_name),char_name);

	//2.得到 传递过来的指针指向的大小,指针指向的是 "char*name",大小是9
	int shicanzhizhennamelen = strlen(char_zhizhen_name) + 1;
	cout << "shicanzhizhennamelen = " << shicanzhizhennamelen << endl;
	this->_char_zhizhen_name = new char[shicanzhizhennamelen];
	memset(this->_char_zhizhen_name, 0, shicanzhizhennamelen);
	strcpy_s(this->_char_zhizhen_name, shicanzhizhennamelen, char_zhizhen_name);

	cout << "断点在这里" << endl;


}
//析构函数
Teacher15::~Teacher15() {
	if (this->_char_zhizhen_name != nullptr) {
		delete [] this->_char_zhizhen_name;
		this->_char_zhizhen_name = nullptr;
	}
}

//operator=操作符



//构造函数定义
Teacher15::Teacher15( )
{
	cout << "Teacher15 没有参数的构造函数调用" << endl;
}

Teacher15::Teacher15( int age) :_age(age) {
// C++编译器实际上会默认加了一个 this参数,且这个this只能指向自己。因此this要用const修饰。 
//Teacher14::Teacher15(Teacher13* const this, int age) :_age(age) {
	cout << "Teacher15 int age,的构造函数调用" << endl;
	this->_age = age;//注意,this指向的值是可以改动的,不然this->age 就不能改变
}

//注意,这里如果是 c 字符串的char [], 无法使用 构造函数初始化列表参数
//Teacher9::Teacher9(int age, char *name) :_age(age),_name(name){//这里有build error,
//那么如果是char [],怎么弄呢?请使用string
Teacher15::Teacher15(int age, string name):_age(age),_name(name) {
	cout << "Teacher15 int age, char name[64] 的构造函数调用" << endl;
}

Teacher15::Teacher15(int age, string name, double score) :_age(age), _name(name), _score(score) {
	cout << "Teacher15 int age, char name[64],double score 的构造函数调用" << endl;
}

Teacher15::Teacher15(int age, string name, double score, int number):_age(age),_name(name),_score(score),_number(number) {
	cout << "Teacher15 int age, char name[64],double score,int number 的构造函数调用" << endl;
}

void Teacher15::printTeacher15() {
	cout << "address = " << this << " age = " << this->_age 
		<< " name = " << this->_name 
		<<" char_name = " <_char_name
		<<" _char_zhizhen_name = " <_char_zhizhen_name
		<< " score = " << this->_score 
		<< " number = " <_number
		<< endl;
}

//const 要加在成员函数后面,表示在该函数中不能改动 成员变量的值
void Teacher15::subTeacher15() const {
	cout << " subTeacher15 const 后面 " << " age - score = " << _age - _score << endl;
	//this->_age = 88;//const 修饰的函数表示不能改动 成员变量
	//this->_score = 90.0;
	_number = 90;//const 修饰的函数表示不能改动 成员变量,但是如果是 mutable修饰的,则可以改动
}

main.cpp

//十一 构造函数分析 ,赋值运算符重载 参考teacher15.h teacher15.cpp
#include "teacher15.h"

void main() {

	Teacher15 tea1(20,"zhangsan",
		(char *)"[][][][][][][][]",
		(char *)"charname****charname",
		98.8,
		800);
	tea1.printTeacher15();

	Teacher15 tea2 = tea1; //会调用拷贝构造函数
	tea2.printTeacher15();

	Teacher15 tea3;
	tea3 = tea2; // 会调用 operator=()函数,这里在teacher15.h 和 teacher15.cpp中重写了operator=()函数
	tea3.printTeacher15();

	string *s1 = new string[10];
	s1->append("123456789");
	cout << s1 << endl;
	cout << *s1 << endl;
	delete []s1;

	cout << "断点在这里" << endl;
}

十三 析构函数

只能有一个,不能重载

    //析构函数
public:
    ~Teacher15();

作用:在执行完成 方法体的代码后,系统会销毁类对象。

系统销毁的顺序是:先定义的后销毁。

我们new 的堆空间,要释放,释放的时机有时候就在析构函数中。

如果new 的时候该变量是在局部变量中,且需要在析构函数中释放,可以将该变量记住,记在一个在析构函数中可以访问的地方。

十四,子类和父类--继承

定义:

class son: public parent{

}

含义:

//public 继承,会继承父类的 public成员(在子类中也是public成员),protected成员(在子类中也是protected成员),不会继承private成员
//protected 继承,会继承父类的 public成员(在子类中变成 protected 成员),protected成员(在子类中也是protected成员),不会继承private成员
//private 继承,会继承父类的 public成员(在子类中也是private成员),protected成员(在子类中变成private成员),不会继承private成员
//实际中一般会用到 public 继承

继承中的构造函数调用顺序

1.先调用父类相关类的构造函数

2.再调用父类的构造函数

3.再调用子类相关类的构造函数

4.再调用子类的构造函数

继承后的 构造成员初始化列表

son1::son1(int parentage, 
	string parentname, 
	double parentnumber,
	int sonage, 
	string sonname, 
	double sonnumber):m_son1_age(sonage),
	m_son1_name(sonname),
	m_son1_number(sonnumber),
	Parent1(parentage, parentname, parentnumber)
{
	cout << "son1 int parentage, string parentname,double parentnumber,int sonage,string sonname,double sonnumber构造函数调用" << endl;
}

函数屏蔽 - 函数重定义。

在子类中如果有和父类名字一样的函数,即使函数参数个数不同,或者类型不同,

在main.cpp中都无法再调用到父类的该方法。

取消函数屏蔽 - 

在子类的.h中,写

using parent::屏蔽函数名。

这样在main.cpp中就可以 调用父类中被屏蔽的 函数 了。

注意的是:取消函数屏蔽 后, main.cpp中就可以调用父类屏蔽的所有同名的函数都可以调用

假设 在父类中有三个:

int funcpingbi(int age) ;

int funcpingbi() ;

int funcpingbi(int age , string name) ;

parent1.h

#pragma once
#include 
#include 
using namespace std;

class Parent1 {

public:
	int m_parent_age;
protected:
	string m_parent_name;
private:
	double m_parent_number;

public:
	//构造方法
	Parent1();
	Parent1(int age,string name, double number);

	//拷贝构造方法
	Parent1(const Parent1& obj);

	//赋值运算符重写
	Parent1 & operator=(const Parent1& obj);
public:
	void printparent1();
	void printparent1(int age);
	void printparent1(int age, string name);
};

parent1.cpp

#include "parent1.h"

Parent1::Parent1() {
	cout << "Parent1 构造函数调用" << endl;
}
Parent1::Parent1(int age, string name , double number)
	:m_parent_age(age),m_parent_name(name),m_parent_number(number) {
	cout << "Parent1 int age, string name , double number 构造函数调用" << endl;
}

//拷贝构造方法
Parent1::Parent1(const Parent1& obj) {
	this->m_parent_age = obj.m_parent_age;
	this->m_parent_name = obj.m_parent_name;
	this->m_parent_number = obj.m_parent_number;
	cout << "parent1 的拷贝构造函数被调用 " << endl;
}

//赋值运算符重写
Parent1 & Parent1::operator=(const Parent1& obj) {
	this->m_parent_age = obj.m_parent_age;
	this->m_parent_name = obj.m_parent_name;
	this->m_parent_number = obj.m_parent_number;
	cout << "parent1 的=号运算符重载调用 " << endl;
	return *this;
}

void Parent1::printparent1() {
	cout << "printparent1 m_parent_age = " << this->m_parent_age 
		<< " m_parent_name = " << this->m_parent_name 
		<< " m_parent_number = " << this->m_parent_number 
		<< endl;
}

void Parent1::printparent1(int age) {
	cout << "printparent1 1个参数 m_parent_age = " << this->m_parent_age
		<< endl;
}

void Parent1::printparent1(int age, string name) {
	cout << "printparent1 2个参数 m_parent_age = " << this->m_parent_age
		<< " m_parent_name = " << this->m_parent_name
		<< endl;
}

son1.h

#pragma once
#include "parent1.h";

//public 继承,会继承父类的 public成员(在子类中也是public成员),protected成员(在子类中也是protected成员),不会继承private成员
//protected 继承,会继承父类的 public成员(在子类中变成 protected 成员),protected成员(在子类中也是protected成员),不会继承private成员
//private 继承,会继承父类的 public成员(在子类中也是private成员),protected成员(在子类中变成private成员),不会继承private成员
//实际中一般会用到 public 继承
class son1 : public Parent1
{
public:
	int m_son1_age;
protected:
	string m_son1_name;
private:
	double m_son1_number;

public:
	son1();
	son1(int parentage, string parentname, double parentnumber, int sonage, string sonname, double sonnumber);
public:
	void printson1();

	//子类中有和父类同名的函数(函数参数个数和类型都可以不同),都会遮蔽父类的函数,这会让在main.cpp中无法再调用名字为 printparent1的所有函数。 这个叫做函数重定义
	void printparent1(int age, string name, double number);

public:
	using Parent1::printparent1;//声明,将子类屏蔽父类的函数 printparent1 关闭,因此可以在 main.cpp中调用了
};

son1.cpp

#include "son1.h"

son1::son1() {
	cout << "son1 构造函数调用" << endl;
}
son1::son1(int parentage, 
	string parentname, 
	double parentnumber,
	int sonage, 
	string sonname, 
	double sonnumber):m_son1_age(sonage),
	m_son1_name(sonname),
	m_son1_number(sonnumber),
	Parent1(parentage, parentname, parentnumber)
{
	cout << "son1 int parentage, string parentname,double parentnumber,int sonage,string sonname,double sonnumber构造函数调用" << endl;
}

void son1::printson1() {
	cout << "printson1 m_parent_age = " << this->m_parent_age 
		<< "  m_parent_name = " << this->m_parent_name 
		<< "   m_son1_age = " << this->m_son1_age 
		<< " m_son1_name =  " << this->m_son1_name 
		<< " m_son1_number = " <<  this->m_son1_number 
		<< endl;
}

void son1::printparent1(int age, string name, double number) {
	cout << "son printparent1" << endl;
}


main.cpp

//十四,子类和父类的 参考 parent1.h,parent1.cpp,son1.h,son1.cpp
#include "son1.h"
void main() {
	son1 s1(100,"zhangsan",98.9,78,"zhangsi",89.8);
	//因为子类重定义了printparent1方法, 且有三个参数,
	//因此这样写调用不到父类的printparent1函数.
	//但是son.h中 在使用了 using Parent1::printparent1;会关闭 屏蔽的函数就可以调用了
	s1.printparent1();//这会调用父类的printparent1无参数的方法
	s1.printparent1(89,"s",78.9);//这会调用子类的printparent1的四个参数的方法
	s1.printson1();
}

十五:继承中的构造函数调用顺序验证

//参考 parent2.h, parent2.cpp, parentfriend2.h, parentfriend2.cpp,
//参考 son2.h, son2.cpp,son2friend2.h, son2friend2.cpp

parentfriend2 构造方法调用
Parent2 构造函数调用  
son2friend2 构造方法调用
son2 构造方法调用

parentfriend2.h

#pragma once

#include 
#include 
using namespace std;

class parentfriend2 {

public:
	int m_parentfriend_age;
protected:
	string m_parentfriend_name;
private:
	double m_parentfriend_number;

public:
	//构造方法
	parentfriend2(int age, string name, double number);

	//拷贝构造方法
	parentfriend2(const parentfriend2& obj);

	//赋值运算符重写
	parentfriend2 & operator=(const parentfriend2& obj);

};

parentfriend2.cpp

#include "parentfriend2.h"

parentfriend2::parentfriend2(int age, string name, double number)
{
	this->m_parentfriend_age = age;
	this->m_parentfriend_name = name;
	this->m_parentfriend_number = number;
	cout << "parentfriend2 构造方法 int age, string name, double number " << endl;
}

//拷贝构造函数
parentfriend2::parentfriend2(const parentfriend2 & obj)
{
	this->m_parentfriend_age = obj.m_parentfriend_age;
	this->m_parentfriend_name = obj.m_parentfriend_name;
	this->m_parentfriend_number = obj.m_parentfriend_number;
	cout << "parentfriend2 拷贝构造函数 被调用 int age, string name, double number" << endl;
}

parentfriend2 & parentfriend2::operator=(const parentfriend2 & obj)
{
	this->m_parentfriend_age = obj.m_parentfriend_age;
	this->m_parentfriend_name = obj.m_parentfriend_name;
	this->m_parentfriend_number = obj.m_parentfriend_number;
	cout << "parentfriend2 赋值等号运算符 被调用 int age, string name, double number" << endl;
	return *this;
}

parent2.h

#pragma once
#include 
#include 
#include "parentfriend2.h"

using namespace std;

class Parent2 {

public:
	int m_parent_age;
	parentfriend2 m_parentfriend;
protected:
	string m_parent_name;
private:
	double m_parent_number;

public:
	//构造方法
	Parent2(int age,string name, double number);

	Parent2(int age, string name, double number, parentfriend2 pf);

	Parent2(int age, string name, double number, int parentfriend2age,string parentfriend2name, double parentfriend2number);

	//拷贝构造方法
	Parent2(const Parent2& obj);

	//赋值运算符重写
	Parent2 & operator=(const Parent2& obj);

public:
	void printParent2();
};

parent2.cpp

#include "parent2.h"

Parent2::Parent2(int age, string name , double number)
	:m_parent_age(age),m_parent_name(name),m_parent_number(number),m_parentfriend(20, "parentfriend2", 200) {
	//this->m_parentfriend = parentfriend2(20,"parentfriend2",200);
	cout << "Parent2 构造函数调用 int age, string name , double number " << endl;
}

Parent2::Parent2(int age, string name, double number,parentfriend2 pf)
	: m_parent_age(age), m_parent_name(name), m_parent_number(number), m_parentfriend(pf) {
	cout << "Parent2 构造函数调用 int age, string name , double number, parentfriend2 pf" << endl;
}

Parent2::Parent2(int age, 
				string name, 
				double number, 
				int parentfriend2age, 
				string parentfriend2name, 
				double parentfriend2number) : 
	m_parent_age(age), 
	m_parent_name(name), 
	m_parent_number(number), 
	m_parentfriend(parentfriend2age, parentfriend2name, parentfriend2number) {
	cout << "Parent2 构造函数调用 int age, string name , double number, 	int parentfriend2age, string parentfriend2name, double parentfriend2number" << endl;
}

//拷贝构造方法
Parent2::Parent2(const Parent2& obj):m_parentfriend(m_parentfriend) {
	this->m_parent_age = obj.m_parent_age;
	this->m_parent_name = obj.m_parent_name;
	this->m_parent_number = obj.m_parent_number;
	this->m_parentfriend = obj.m_parentfriend;
	cout << "parent1 的拷贝构造函数被调用 " << endl;
}

//赋值运算符重写
Parent2 & Parent2::operator=(const Parent2& obj) {
	this->m_parent_age = obj.m_parent_age;
	this->m_parent_name = obj.m_parent_name;
	this->m_parent_number = obj.m_parent_number;
	this->m_parentfriend = obj.m_parentfriend;
	cout << "parent1 的=号运算符重载调用 " << endl;
	return *this;
}

void Parent2::printParent2() {
	cout << "   this->m_parent_age = " << this->m_parent_age
		<< "   this->m_parent_name = " << this->m_parent_name
		<< "   this->m_parent_number = " << this->m_parent_number
		<< "   this->m_parentfriend.m_parentfriend_age = " << this->m_parentfriend.m_parentfriend_age
		<< endl;
}

son2friend2.h

#pragma once
#include 
#include 

using namespace std;

class son2friend2
{

public:
	int m_son2friend_age;
protected:
	string m_son2friend_name;
private:
	double m_son2friend_number;

public:
	//构造方法
	son2friend2(int age, string name, double number);

	//拷贝构造方法
	son2friend2(const son2friend2& obj);

	//赋值运算符重写
	son2friend2 & operator=(const son2friend2& obj);

};

son2friend2.cpp

#include "son2friend2.h"

son2friend2::son2friend2(int age, string name, double number)
	:m_son2friend_age(age),m_son2friend_name(name),m_son2friend_number(number)
{
	cout << "son2friend2 构造方法调用" << endl;
}

son2friend2::son2friend2(const son2friend2 & obj)
{
	cout << "son2friend2 拷贝构造方法调用" << endl;
	this->m_son2friend_age = obj.m_son2friend_age;
	this->m_son2friend_name = obj.m_son2friend_name;
	this->m_son2friend_number = obj.m_son2friend_number;

}

son2friend2 & son2friend2::operator=(const son2friend2 & obj)
{
	cout << "son2friend2 赋值运算符重载调用" << endl;
	this->m_son2friend_age = obj.m_son2friend_age;
	this->m_son2friend_name = obj.m_son2friend_name;
	this->m_son2friend_number = obj.m_son2friend_number;
	return *this;
}


son2.h

#pragma once
#include "parent2.h"
#include "son2friend2.h"
class son2 :public Parent2
{
public:
		int m_son2age;
		son2friend2 son2friend;
protected:
		string m_son2name;
private:
		double m_son2number;

public:
	son2(int age,
		string name,
		double number,
		int sonfriendage,
		string sonfriendname,
		double sonfriendnumber,
		int parentage,
		string parentname,
		double parentnumber,
		int parentfriend2age,
		string parentfriend2name,
		double parentfriend2number);
		
	void printson2();

};

子类的 初始化成员列表 实现

son2.cpp

#include "son2.h"

son2::son2(int age, string name, double number,
	int sonfriendage, string sonfriendname, double sonfriendnumber,
	int parentage, string parentname, double parentnumber, 
	int parentfriend2age, string parentfriend2name, double parentfriend2number)
	:son2friend(sonfriendage, sonfriendname, sonfriendnumber),
	m_son2age(age), m_son2name(name), m_son2number(number),
	Parent2(parentage, parentname, parentnumber, parentfriend2age, parentfriend2name, parentfriend2number)
{
	cout << "son2 构造方法" << endl;
}

void son2::printson2()
{

	cout << "  m_son2age = " << this->m_son2age 
		<< "   m_son2name = " << this->m_son2name 
		<< "   m_son2number = " << this->m_son2number
		<< "   son2friend.m_son2friend_age = " << this->son2friend.m_son2friend_age
		<< "   m_parent_age = " << this->m_parent_age
		<< "   m_parent_name = " << this->m_parent_name
		<< "   m_parentfriend.m_parentfriend_age = " <m_parentfriend.m_parentfriend_age
		<

main.cpp

#include "parent2.h"
#include "son2.h"

void main() {
	cout << "111" << endl;
	Parent2 pa(999,"nihao",89.9);
	pa.printParent2();

	cout << "222" << endl;

	Parent2 pa1(19090, "wer", 888.89, 111, "iop", 9.6);
	pa1.printParent2();

	cout << "333" << endl;

	son2 son2(1,"son",11.1,2,"sonfriend",22.2,3,"parent",33.3,4,"parentfriend",44.4);
	son2.printson2();
	cout << "444" << endl;
	son2.printParent2();

}

运行结果:

111
parentfriend2 构造方法 int age, string name, double number
Parent2 构造函数调用 int age, string name , double number
   this->m_parent_age = 999   this->m_parent_name = nihao   this->m_parent_number = 89.9   this->m_parentfriend.m_parentfriend_age = 20

222

parentfriend2 构造方法 int age, string name, double number
Parent2 构造函数调用 int age, string name , double number,      int parentfriend2age, string parentfriend2name, double parentfriend2number
   this->m_parent_age = 19090   this->m_parent_name = wer   this->m_parent_number = 888.89   this->m_parentfriend.m_parentfriend_age = 111

333

parentfriend2 构造方法 int age, string name, double number
Parent2 构造函数调用 int age, string name , double number,      int parentfriend2age, string parentfriend2name, double parentfriend2number
son2friend2 构造方法调用
son2 构造方法
  m_son2age = 1   m_son2name = son   m_son2number = 11.1   son2friend.m_son2friend_age = 2   m_parent_age = 3   m_parent_name = parent   m_parentfriend.m_parentfriend_age4

444

   this->m_parent_age = 3   this->m_parent_name = parent   this->m_parent_number = 33.3   this->m_parentfriend.m_parentfriend_age = 4

你可能感兴趣的:(c++)