c++类和对象

C动态分配内存方法

在这里插入图片描述

class Person{

public:

Person(){

mAge = 20;

pName = (char*)malloc(strlen(“john”)+1);

strcpy(pName, “john”);

}

void Init(){

mAge = 20;

pName = (char*)malloc(strlen(“john”)+1);

strcpy(pName, “john”);

}

void Clean(){

if (pName != NULL){

free(pName);

}

}

public:

int mAge;

char* pName;

};

int main(){

//分配内存

Person* person = (Person*)malloc(sizeof(Person));

if(person == NULL){

return 0;

}

//调用初始化函数

person->Init();

//清理对象

person->Clean();

//释放person对象

free(person);

return EXIT_SUCCESS;

}

在这里插入图片描述

new operator

在这里插入图片描述

delete operator

在这里插入图片描述

class Person{

public:

Person(){

cout << “无参构造函数!” << endl;

pName = (char*)malloc(strlen(“undefined”) + 1);

strcpy(pName, “undefined”);

mAge = 0;

}

Person(char* name, int age){

cout << “有参构造函数!” << endl;

pName = (char*)malloc(strlen(name) + 1);

strcpy(pName, name);

mAge = age;

}

void ShowPerson(){

cout << “Name:” << pName << " Age:" << mAge << endl;

}

~Person(){

cout << “析构函数!” << endl;

if (pName != NULL){

delete pName;

pName = NULL;

}

}

public:

char* pName;

int mAge;

};

void test(){

Person* person1 = new Person;

Person* person2 = new Person(“John”,33);

person1->ShowPerson();

person2->ShowPerson();

delete person1;

delete person2;

}

用于数组的new和delete

在这里插入图片描述

class Person{

public:

Person(){

pName = (char*)malloc(strlen(“undefined”) + 1);

strcpy(pName, “undefined”);

mAge = 0;

}

Person(char* name, int age){

pName = (char*)malloc(sizeof(name));

strcpy(pName, name);

mAge = age;

}

~Person(){

if (pName != NULL){

delete pName;

}

}

public:

char* pName;

int mAge;

};

void test(){

//栈聚合初始化

Person person[] = { Person(“john”, 20), Person(“Smith”, 22) };

cout << person[1].pName << endl;

//创建堆上对象数组必须提供构造函数

Person* workers = new Person[20];

}

delete void*可能会出错

在这里插入图片描述

在这里插入图片描述

使用new和delete采用相同形式

在这里插入图片描述

在这里插入图片描述

10.静态成员

在这里插入图片描述

静态成员变量

在这里插入图片描述

class Person{

public:

//类的静态成员属性

static int sNum;

private:

static int sOther;

};

//类外初始化,初始化时不加static

int Person::sNum = 0;

int Person::sOther = 0;

int main(){

//1. 通过类名直接访问

Person::sNum = 100;

cout << “Person::sNum:” << Person::sNum << endl;

//2. 通过对象访问

Person p1, p2;

p1.sNum = 200;

cout << “p1.sNum:” << p1.sNum << endl;

cout << “p2.sNum:” << p2.sNum << endl;

//3. 静态成员也有访问权限,类外不能访问私有成员

//cout << “Person::sOther:” << Person::sOther << endl;

Person p3;

//cout << “p3.sOther:” << p3.sOther << endl;

system(“pause”);

return EXIT_SUCCESS;

}

静态成员函数

在这里插入图片描述

class Person{

public:

//普通成员函数可以访问static和non-static成员属性

void changeParam1(int param){

mParam = param;

sNum = param;

}

//静态成员函数只能访问static成员属性

static void changeParam2(int param){

//mParam = param; //无法访问

sNum = param;

}

private:

static void changeParam3(int param){

//mParam = param; //无法访问

sNum = param;

}

public:

int mParam;

static int sNum;

};

//静态成员属性类外初始化

int Person::sNum = 0;

int main(){

//1. 类名直接调用

Person::changeParam2(100);

//2. 通过对象调用

Person p;

p.changeParam2(200);

//3. 静态成员函数也有访问权限

//Person::changeParam3(100); //类外无法访问私有静态成员函数

//Person p1;

//p1.changeParam3(200);

return EXIT_SUCCESS;

}

const静态成员属性

在这里插入图片描述

静态成员实现单例模式

在这里插入图片描述

class Printer{

public:

static Printer* getInstance(){ return pPrinter;}

void PrintText(string text){

cout << “打印内容:” << text << endl;

cout << “已打印次数:” << mTimes << endl;

cout << “--------------” << endl;

mTimes++;

}

private:

Printer(){ mTimes = 0; }

Printer(const Printer&){}

private:

static Printer* pPrinter;

int mTimes;

};

Printer* Printer::pPrinter = new Printer;

void test(){

Printer* printer = Printer::getInstance();

printer->PrintText(“离职报告!”);

printer->PrintText(“入职合同!”);

printer->PrintText(“提交代码!”);

}

四、C++面向对象模型初探


1.成员变量和函数的存储

在这里插入图片描述

class MyClass01{

public:

int mA;

};

class MyClass02{

public:

int mA;

static int sB;

};

class MyClass03{

public:

void printMyClass(){

cout << “hello world!” << endl;

}

public:

int mA;

static int sB;

};

class MyClass04{

public:

void printMyClass(){

cout << “hello world!” << endl;

}

static void ShowMyClass(){

cout << “hello world!” << endl;

}

public:

int mA;

static int sB;

};

int main(){

MyClass01 mclass01;

MyClass02 mclass02;

MyClass03 mclass03;

MyClass04 mclass04;

cout << “MyClass01:” << sizeof(mclass01) << endl; //4

//静态数据成员并不保存在类对象中

cout << “MyClass02:” << sizeof(mclass02) << endl; //4

//非静态成员函数不保存在类对象中

cout << “MyClass03:” << sizeof(mclass03) << endl; //4

//静态成员函数也不保存在类对象中

cout << “MyClass04:” << sizeof(mclass04) << endl; //4

return EXIT_SUCCESS;

}

在这里插入图片描述

2.this指针

this指针工作原理

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

this指针的使用

在这里插入图片描述

class Person{

public:

//1. 当形参名和成员变量名一样时,this指针可用来区分

Person(string name,int age){

//name = name;

//age = age; //输出错误

this->name = name;

this->age = age;

}

//2. 返回对象本身的引用

//重载赋值操作符

//其实也是两个参数,其中隐藏了一个this指针

Person PersonPlusPerson(Person& person){

string newname = this->name + person.name;

int newage = this->age + person.age;

Person newperson(newname, newage);

return newperson;

}

void ShowPerson(){

cout << “Name:” << name << " Age:" << age << endl;

}

public:

string name;

int age;

};

//3. 成员函数和全局函数(Perosn对象相加)

Person PersonPlusPerson(Person& p1,Person& p2){

string newname = p1.name + p2.name;

int newage = p1.age + p2.age;

Person newperson(newname,newage);

return newperson;

}

int main(){

Person person(“John”,100);

person.ShowPerson();

cout << “---------” << endl;

Person person1(“John”,20);

Person person2(“001”, 10);

//1.全局函数实现两个对象相加

Person person3 = PersonPlusPerson(person1, person2);

person1.ShowPerson();

person2.ShowPerson();

person3.ShowPerson();

//2. 成员函数实现两个对象相加

Person person4 = person1.PersonPlusPerson(person2);

person4.ShowPerson();

system(“pause”);

return EXIT_SUCCESS;

}

const修饰成员函数

在这里插入图片描述

//const修饰成员函数

class Person{

public:

Person(){

this->mAge = 0;

this->mID = 0;

}

//在函数括号后面加上const,修饰成员变量不可修改,除了mutable变量

void sonmeOperate() const{

//this->mAge = 200; //mAge不可修改

this->mID = 10;

}

void ShowPerson(){

cout << “ID:” << mID << " mAge:" << mAge << endl;

}

private:

int mAge;

mutable int mID;

};

int main(){

Person person;

person.sonmeOperate();

person.ShowPerson();

system(“pause”);

return EXIT_SUCCESS;

}

const修饰对象(常对象)

在这里插入图片描述

class Person{

public:

Person(){

this->mAge = 0;

this->mID = 0;

}

void ChangePerson() const{

mAge = 100;

mID = 100;

}

void ShowPerson(){

this->mAge = 1000;

cout << “ID:” << this->mID << " Age:" << this->mAge << endl;

}

public:

int mAge;

mutable int mID;

};

void test(){

const Person person;

//1. 可访问数据成员

cout << “Age:” << person.mAge << endl;

//person.mAge = 300; //不可修改

person.mID = 1001; //但是可以修改mutable修饰的成员变量

//2. 只能访问const修饰的函数

//person.ShowPerson();

person.ChangePerson();

}

五、友元


在这里插入图片描述

1.友元语法

在这里插入图片描述

class Building;

//友元类

class MyFriend{

public:

//友元成员函数

void LookAtBedRoom(Building& building);

void PlayInBedRoom(Building& building);

};

class Building{

//全局函数做友元函数

friend void CleanBedRoom(Building& building);

#if 0

//成员函数做友元函数

friend void MyFriend::LookAtBedRoom(Building& building);

friend void MyFriend::PlayInBedRoom(Building& building);

#else

//友元类

friend class MyFriend;

#endif

public:

Building();

public:

string mSittingRoom;

private:

string mBedroom;

};

void MyFriend::LookAtBedRoom(Building& building){

cout << “我的朋友参观” << building.mBedroom << endl;

}

void MyFriend::PlayInBedRoom(Building& building){

cout << “我的朋友玩耍在” << building.mBedroom << endl;

}

//友元全局函数

void CleanBedRoom(Building& building){

cout << “友元全局函数访问” << building.mBedroom << endl;

}

Building::Building(){

this->mSittingRoom = “客厅”;

this->mBedroom = “卧室”;

}

int main(){

Building building;

MyFriend myfriend;

CleanBedRoom(building);

myfriend.LookAtBedRoom(building);

myfriend.PlayInBedRoom(building);

system(“pause”);

return EXIT_SUCCESS;

}

在这里插入图片描述

2.课堂练习

在这里插入图片描述

class Remote;

class Television{

friend class Remote;

public:

enum{ On,Off }; //电视状态

enum{ minVol,maxVol = 100 }; //音量从0到100

enum{ minChannel = 1,maxChannel = 255 }; //频道从1到255

Television(){

mState = Off;

mVolume = minVol;

mChannel = minChannel;

}

//打开电视机

void OnOrOff(){

this->mState = (this->mState == On ? Off : On);

}

//调高音量

void VolumeUp(){

if (this->mVolume >= maxVol){

return;

}

this->mVolume++;

}

//调低音量

void VolumeDown(){

if (this->mVolume <= minVol){

return;

}

this->mVolume–;

}

//更换电视频道

void ChannelUp(){

if (this->mChannel >= maxChannel){

return;

}

this->mChannel++;

}

void ChannelDown(){

if (this->mChannel <= minChannel){

return;

}

this->mChannel–;

}

//展示当前电视状态信息

void ShowTeleState(){

cout << “开机状态:” << (mState == On ? “已开机” : “已关机”) << endl;

if (mState == On){

cout << “当前音量:” << mVolume << endl;

cout << “当前频道:” << mChannel << endl;

}

cout << “-------------” << endl;

}

private:

int mState; //电视状态,开机,还是关机

int mVolume; //电视机音量

int mChannel; //电视频道

};

//电视机调台只能一个一个的调,遥控可以指定频道

//电视遥控器

class Remote{

public:

Remote(Television* television){

pTelevision = television;

}

public:

void OnOrOff(){

pTelevision->OnOrOff();

}

//调高音量

void VolumeUp(){

pTelevision->VolumeUp();

}

//调低音量

void VolumeDown(){

pTelevision->VolumeDown();

}

//更换电视频道

void ChannelUp(){

pTelevision->ChannelUp();

}

void ChannelDown(){

pTelevision->ChannelDown();

}

//设置频道 遥控新增功能

void SetChannel(int channel){

if (channel < Television::minChannel || channel > Television::maxChannel){

return;

}

pTelevision->mChannel = channel;

}

//显示电视当前信息

void ShowTeleState(){

pTelevision->ShowTeleState();

}

private:

Television* pTelevision;

};

//直接操作电视

void test01(){

Television television;

television.ShowTeleState();

television.OnOrOff(); //开机

television.VolumeUp(); //增加音量+1

television.VolumeUp(); //增加音量+1

television.VolumeUp(); //增加音量+1

television.VolumeUp(); //增加音量+1

television.ChannelUp(); //频道+1

television.ChannelUp(); //频道+1

television.ShowTeleState();

}

//通过遥控操作电视

void test02(){

//创建电视

Television television;

//创建遥控

Remote remote(&television);

remote.OnOrOff();

remote.ChannelUp();//频道+1

remote.ChannelUp();//频道+1

remote.ChannelUp();//频道+1

remote.VolumeUp();//音量+1

remote.VolumeUp();//音量+1

remote.VolumeUp();//音量+1

remote.VolumeUp();//音量+1

remote.ShowTeleState();

}

六、运算符重载


1.运算符重载基本概念

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

2.运算符重载碰上友元函数

在这里插入图片描述

class Person{

friend ostream& operator<<(ostream& os, Person& person);

public:

Person(int id,int age){

mID = id;

mAge = age;

}

private:

int mID;

int mAge;

};

ostream& operator<<(ostream& os, Person& person){

os << “ID:” << person.mID << " Age:" << person.mAge;

return os;

}

int main(){

Person person(1001, 30);

//cout << person; //cout.operator+(person)

cout << person << " | " << endl;

return EXIT_SUCCESS;

}

3.可重载的运算符

在这里插入图片描述

4.自增自减(++/–)运算符重载

在这里插入图片描述

class Complex{

friend ostream& operator<<(ostream& os,Complex& complex){

os << “A:” << complex.mA << " B:" << complex.mB << endl;

return os;

}

public:

Complex(){

mA = 0;

mB = 0;

}

//重载前置++

Complex& operator++(){

mA++;

mB++;

return *this;

}

//重载后置++

Complex operator++(int){

Complex temp;

temp.mA = this->mA;

temp.mB = this->mB;

mA++;

mB++;

return temp;

}

//前置–

Complex& operator–(){

mA–;

mB–;

return *this;

}

//后置–

Complex operator–(int){

Complex temp;

temp.mA = mA;

temp.mB = mB;

mA–;

mB–;

return temp;

}

void ShowComplex(){

cout << “A:” << mA << " B:" << mB << endl;

}

private:

int mA;

int mB;

};

void test(){

Complex complex;

complex++;

cout << complex;

++complex;

cout << complex;

Complex ret = complex++;

cout << ret;

cout << complex;

cout << “------” << endl;

ret–;

–ret;

cout << “ret:” << ret;

complex–;

–complex;

cout << “complex:” << complex;

}

在这里插入图片描述

5.指针运算符(*、->)重载

class Person{

public:

Person(int param){

this->mParam = param;

}

void PrintPerson(){

cout << “Param:” << mParam << endl;

}

private:

int mParam;

};

class SmartPointer{

public:

SmartPointer(Person* person){

this->pPerson = person;

}

//重载指针的->、*操作符

Person* operator->(){

return pPerson;

}

Person& operator*(){

return *pPerson;

}

~SmartPointer(){

if (pPerson != NULL){

delete pPerson;

}

}

public:

Person* pPerson;

};

void test01(){

//Person* person = new Person(100);

//如果忘记释放,那么就会造成内存泄漏

SmartPointer pointer(new Person(100));

pointer->PrintPerson();

}

6.赋值(=)运算符重载

在这里插入图片描述

class Person{

friend ostream& operator<<(ostream& os,const Person& person){

os << “ID:” << person.mID << " Age:" << person.mAge << endl;

return os;

}

public:

Person(int id,int age){

this->mID = id;

this->mAge = age;

}

//重载赋值运算符

Person& operator=(const Person& person){

this->mID = person.mID;

this->mAge = person.mAge;

return *this;

}

private:

int mID;

int mAge;

};

//1. =号混淆的地方

void test01(){

Person person1(10, 20);

Person person2 = person1; //调用拷贝构造

//如果一个对象还没有被创建,则必须初始化,也就是调用构造函数

//上述例子由于person2还没有初始化,所以会调用构造函数

//由于person2是从已有的person1来创建的,所以只有一个选择

//就是调用拷贝构造函数

person2 = person1; //调用operator=函数

//由于person2已经创建,不需要再调用构造函数,这时候调用的是重载的赋值运算符

}

//2. 赋值重载案例

void test02(){

Person person1(20, 20);

Person person2(30, 30);

cout << “person1:” << person1;

cout << “person2:” << person2;

person2 = person1;

cout << “person2:” << person2;

}

//常见错误,当准备给两个相同对象赋值时,应该首先检查一下这个对象是否对自身赋值了

//对于本例来讲,无论如何执行这些赋值运算都是无害的,但如果对类的实现进行修改,那么将会出现差异;

//3. 类中指针

class Person2{

friend ostream& operator<<(ostream& os, const Person2& person){

os << “Name:” << person.pName << " ID:" << person.mID << " Age:" << person.mAge << endl;

return os;

}

public:

Person2(char* name,int id, int age){

this->pName = new char[strlen(name) + 1];

strcpy(this->pName, name);

this->mID = id;

this->mAge = age;

}

#if 1

//重载赋值运算符

Person2& operator=(const Person2& person){

//注意:由于当前对象已经创建完毕,那么就有可能pName指向堆内存

//这个时候如果直接赋值,会导致内存没有及时释放

if (this->pName != NULL){

delete[] this->pName;

}

this->pName = new char[strlen(person.pName) + 1];

strcpy(this->pName,person.pName);

this->mID = person.mID;

this->mAge = person.mAge;

return *this;

}

#endif

//析构函数

~Person2(){

if (this->pName != NULL){

delete[] this->pName;

}

}

private:

char* pName;

int mID;

int mAge;

};

void test03(){

Person2 person1(“John”,20, 20);

Person2 person2(“Edward”,30, 30);

cout << “person1:” << person1;

cout << “person2:” << person2;

person2 = person1;

cout << “person2:” << person2;

}

在这里插入图片描述

7.等于和不等于(==、!=)运算符重载

class Complex{

public:

Complex(char* name,int id,int age){

this->pName = new char[strlen(name) + 1];

strcpy(this->pName, name);

this->mID = id;

this->mAge = age;

}

//重载==号操作符

bool operator==(const Complex& complex){

if (strcmp(this->pName,complex.pName) == 0 &&

this->mID == complex.mID &&

this->mAge == complex.mAge){

return true;

}

return false;

}

//重载!=操作符

bool operator!=(const Complex& complex){

if (strcmp(this->pName, complex.pName) != 0 ||

this->mID != complex.mID ||

this->mAge != complex.mAge){

return true;

}

return false;

}

~Complex(){

if (this->pName != NULL){

delete[] this->pName;

}

}

private:

char* pName;

int mID;

int mAge;

};

void test(){

Complex complex1(“aaa”, 10, 20);

Complex complex2(“bbb”, 10, 20);

if (complex1 == complex2){ cout << “相等!” << endl; }

if (complex1 != complex2){ cout << “不相等!” << endl; }

}

8.函数调用符号()重载

class Complex{

public:

int Add(int x,int y){

return x + y;

}

int operator()(int x,int y){

return x + y;

}

};

void test01(){

Complex complex;

cout << complex.Add(10,20) << endl;

//对象当做函数来调用

cout << complex(10, 20) << endl;

}

9.不要重载&&、||

在这里插入图片描述

class Complex{

public:

Complex(int flag){

this->flag = flag;

}

Complex& operator+=(Complex& complex){

this->flag = this->flag + complex.flag;

return *this;

}

bool operator&&(Complex& complex){

return this->flag && complex.flag;

}

public:

int flag;

};

int main(){

Complex complex1(0); //flag 0

Complex complex2(1); //flag 1

//原来情况,应该从左往右运算,左边为假,则退出运算,结果为假

//这边却是,先运算(complex1+complex2),导致,complex1的flag变为complex1+complex2的值, complex1.a = 1

// 1 && 1

//complex1.operator&&(complex1.operator+=(complex2))

if (complex1 && (complex1 += complex2)){

cout << “真!” << endl;

}

else{

cout << “假!” << endl;

}

return EXIT_SUCCESS;

}

在这里插入图片描述

10.符号重载总结

在这里插入图片描述

11.附录:运算符和结合性

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

七、继承和派生


1.继承概述

为什么需要继承

在这里插入图片描述

网页类

class IndexPage{

public:

//网页头部

void Header(){

cout << “网页头部!” << endl;

}

//网页左侧菜单

void LeftNavigation(){

cout << “左侧导航菜单!” << endl;

}

//网页主体部分

void MainBody(){

cout << “首页网页主题内容!” << endl;

}

//网页底部

void Footer(){

cout << “网页底部!” << endl;

}

private:

string mTitle; //网页标题

};

#if 0

//如果不使用继承,那么定义新闻页类,需要重新写一遍已经有的代码

class NewsPage{

public:

//网页头部

void Header(){

cout << “网页头部!” << endl;

}

//网页左侧菜单

void LeftNavigation(){

cout << “左侧导航菜单!” << endl;

}

//网页主体部分

void MainBody(){

cout << “新闻网页主体内容!” << endl;

}

//网页底部

void Footer(){

cout << “网页底部!” << endl;

}

private:

string mTitle; //网页标题

};

void test(){

NewsPage* newspage = new NewsPage;

newspage->Header();

newspage->MainBody();

newspage->LeftNavigation();

newspage->Footer();

}

#else

//使用继承,可以复用已有的代码,新闻业除了主体部分不一样,其他都是一样的

class NewsPage : public IndexPage{

public:

//网页主体部分

void MainBody(){

cout << “新闻网页主主体内容!” << endl;

}

};

void test(){

NewsPage* newspage = new NewsPage;

newspage->Header();

newspage->MainBody();

newspage->LeftNavigation();

newspage->Footer();

}

#endif

int main(){

test();

return EXIT_SUCCESS;

}

继承基本概念

在这里插入图片描述

在这里插入图片描述

派生类定义

在这里插入图片描述

2.派生类访问控制

在这里插入图片描述

在这里插入图片描述

//基类

class A{

public:

int mA;

protected:

int mB;

private:

int mC;

};

//1. 公有(public)继承

class B : public A{

public:

void PrintB(){

cout << mA << endl; //可访问基类public属性

cout << mB << endl; //可访问基类protected属性

//cout << mC << endl; //不可访问基类private属性

}

};

class SubB : public B{

void PrintSubB(){

cout << mA << endl; //可访问基类public属性

cout << mB << endl; //可访问基类protected属性

//cout << mC << endl; //不可访问基类private属性

}

};

void test01(){

B b;

cout << b.mA << endl; //可访问基类public属性

//cout << b.mB << endl; //不可访问基类protected属性

//cout << b.mC << endl; //不可访问基类private属性

}

//2. 私有(private)继承

class C : private A{

public:

void PrintC(){

cout << mA << endl; //可访问基类public属性

cout << mB << endl; //可访问基类protected属性

//cout << mC << endl; //不可访问基类private属性

}

};

class SubC : public C{

void PrintSubC(){

//cout << mA << endl; //不可访问基类public属性

//cout << mB << endl; //不可访问基类protected属性

//cout << mC << endl; //不可访问基类private属性

}

};

void test02(){

C c;

//cout << c.mA << endl; //不可访问基类public属性

//cout << c.mB << endl; //不可访问基类protected属性

//cout << c.mC << endl; //不可访问基类private属性

}

//3. 保护(protected)继承

class D : protected A{

public:

void PrintD(){

cout << mA << endl; //可访问基类public属性

cout << mB << endl; //可访问基类protected属性

//cout << mC << endl; //不可访问基类private属性

}

};

class SubD : public D{

void PrintD(){

cout << mA << endl; //可访问基类public属性

cout << mB << endl; //可访问基类protected属性

//cout << mC << endl; //不可访问基类private属性

}

};

void test03(){

D d;

//cout << d.mA << endl; //不可访问基类public属性

//cout << d.mB << endl; //不可访问基类protected属性

//cout << d.mC << endl; //不可访问基类private属性

}

3.继承中的构造和析构

继承中的对象模型

在这里插入图片描述

对象构造和析构的调用原则

在这里插入图片描述

class A{

public:

A(){

cout << “A类构造函数!” << endl;

}

~A(){

cout << “A类析构函数!” << endl;

}

};

class B : public A{

public:

B(){

cout << “B类构造函数!” << endl;

}

~B(){

cout << “B类析构函数!” << endl;

}

};

class C : public B{

public:

C(){

cout << “C类构造函数!” << endl;

}

~C(){

cout << “C类析构函数!” << endl;

}

};

void test(){

C c;

}

在这里插入图片描述

class D{

public:

D(){

cout << “D类构造函数!” << endl;

}

~D(){

cout << “D类析构函数!” << endl;

}

};

class A{

public:

A(){

cout << “A类构造函数!” << endl;

}

~A(){

cout << “A类析构函数!” << endl;

}

};

class B : public A{

public:

B(){

cout << “B类构造函数!” << endl;

}

~B(){

cout << “B类析构函数!” << endl;

}

};

class C : public B{

public:

C(){

cout << “C类构造函数!” << endl;

}

~C(){

cout << “C类析构函数!” << endl;

}

public:

D c;

};

void test(){

C c;

}

4.继承中同名成员的处理方法

在这里插入图片描述

class Base{

public:

Base():mParam(0){}

void Print(){ cout << mParam << endl; }

public:

int mParam;

};

class Derived : public Base{

public:

Derived():mParam(10){}

void Print(){

//在派生类中使用和基类的同名成员,显示使用类名限定符

cout << Base::mParam << endl;

cout << mParam << endl;

}

//返回基类重名成员

int& getBaseParam(){ return Base::mParam; }

public:

int mParam;

};

int main(){

Derived derived;

//派生类和基类成员属性重名,子类访问成员默认是子类成员

cout << derived.mParam << endl; //10

derived.Print();

//类外如何获得基类重名成员属性

derived.getBaseParam() = 100;

cout << “Base:mParam:” << derived.getBaseParam() << endl;

return EXIT_SUCCESS;

}

注意: 如果重新定义了基类中的重载函数,将会发生什么?

class Base{

public:

void func1(){

cout << “Base::void func1()” << endl;

};

void func1(int param){

cout << “Base::void func1(int param)” << endl;

}

void myfunc(){

cout << “Base::void myfunc()” << endl;

}

};

class Derived1 : public Base{

public:

void myfunc(){

cout << “Derived1::void myfunc()” << endl;

}

};

class Derived2 : public Base{

public:

//改变成员函数的参数列表

void func1(int param1, int param2){

cout << “Derived2::void func1(int param1,int param2)” << endl;

};

};

class Derived3 : public Base{

public:

//改变成员函数的返回值

int func1(int param){

cout << “Derived3::int func1(int param)” << endl;

return 0;

}

};

int main(){

Derived1 derived1;

derived1.func1();

derived1.func1(20);

derived1.myfunc();

cout << “-------------” << endl;

Derived2 derived2;

//derived2.func1(); //func1被隐藏

//derived2.func1(20); //func2被隐藏

derived2.func1(10,20); //重载func1之后,基类的函数被隐藏

derived2.myfunc();

cout << “-------------” << endl;

Derived3 derived3;

//derived3.func1(); 没有重新定义的重载版本被隐藏

derived3.func1(20);

derived3.myfunc();

return EXIT_SUCCESS;

}

在这里插入图片描述

5.非自动继承的函数

在这里插入图片描述

6.继承中的静态成员特性

在这里插入图片描述

在这里插入图片描述

7.多继承

多继承概念

在这里插入图片描述

在这里插入图片描述

菱形继承和虚继承

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

虚继承实现原理

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

八、多态
自我介绍一下,小编13年上海交大毕业,曾经在小公司待过,也去过华为、OPPO等大厂,18年进入阿里一直到现在。

深知大多数Java工程师,想要提升技能,往往是自己摸索成长或者是报班学习,但对于培训机构动则几千的学费,着实压力不小。自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!

因此收集整理了一份《2024年Java开发全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友,同时减轻大家的负担。img

既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,基本涵盖了95%以上Java开发知识点,真正体系化!

由于文件比较大,这里只是将部分目录截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且会持续更新!

如果你觉得这些内容对你有帮助,可以扫码获取!!(备注:Java)

总结

我们总是喜欢瞻仰大厂的大神们,但实际上大神也不过凡人,与菜鸟程序员相比,也就多花了几分心思,如果你再不努力,差距也只会越来越大。实际上,作为程序员,丰富自己的知识储备,提升自己的知识深度和广度是很有必要的。

Mybatis源码解析

《互联网大厂面试真题解析、进阶开发核心学习笔记、全套讲解视频、实战项目源码讲义》点击传送门即可获取!
ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3hpYW90YWkxMjM0,size_16,color_FFFFFF,t_70#pic_center)

在这里插入图片描述

在这里插入图片描述

虚继承实现原理

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

八、多态
自我介绍一下,小编13年上海交大毕业,曾经在小公司待过,也去过华为、OPPO等大厂,18年进入阿里一直到现在。

深知大多数Java工程师,想要提升技能,往往是自己摸索成长或者是报班学习,但对于培训机构动则几千的学费,着实压力不小。自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!

因此收集整理了一份《2024年Java开发全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友,同时减轻大家的负担。[外链图片转存中…(img-j1pAKZtf-1713814937182)]

[外链图片转存中…(img-ZhYHd9v4-1713814937182)]

[外链图片转存中…(img-A5LzB81q-1713814937183)]

既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,基本涵盖了95%以上Java开发知识点,真正体系化!

由于文件比较大,这里只是将部分目录截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且会持续更新!

如果你觉得这些内容对你有帮助,可以扫码获取!!(备注:Java)

[外链图片转存中…(img-wro1OeLt-1713814937183)]

总结

我们总是喜欢瞻仰大厂的大神们,但实际上大神也不过凡人,与菜鸟程序员相比,也就多花了几分心思,如果你再不努力,差距也只会越来越大。实际上,作为程序员,丰富自己的知识储备,提升自己的知识深度和广度是很有必要的。

Mybatis源码解析

[外链图片转存中…(img-T8Rn8vAl-1713814937183)]

[外链图片转存中…(img-svYZaoih-1713814937183)]

《互联网大厂面试真题解析、进阶开发核心学习笔记、全套讲解视频、实战项目源码讲义》点击传送门即可获取!

  • 29
    点赞
  • 14
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值