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(“提交代码!”);
}
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开发全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友,同时减轻大家的负担。
既有适合小白学习的零基础资料,也有适合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)]
《互联网大厂面试真题解析、进阶开发核心学习笔记、全套讲解视频、实战项目源码讲义》点击传送门即可获取!