01 静态成员变量和静态成员函数
1.静态成员变量,在类内声明,类外进行初始化
#define _CRT_SECURE_NO_WARNINGS
#include<iostream>
using namespace std;
class Person
{
public:
Person()
{
//m_Age = 10;
}
static int m_Age;//加入static就是 静态成员变量,会共享数据
//静态成员变量,在类内声明,类外进行初始化
};
int Person::m_Age = 0;//类外初始化实现
void test01()
{
//1.通过对象访问属性
Person p1;
p1.m_Age = 10;
Person p2;
p2.m_Age = 20;
cout << "p1.m_Age:" << p1.m_Age << endl;//20
cout << "p2.m_Age:" << p2.m_Age << endl;//20
}
int main(void)
{
test01();
system("pause");
return EXIT_SUCCESS;
}
2.静态成员变量也是有权限的
#define _CRT_SECURE_NO_WARNINGS
#include<iostream>
using namespace std;
class Person
{
public:
static int m_Age;//加入static就是 静态成员变量,会共享数据
//静态成员变量,在类内声明,类外进行初始化
int m_A;
//静态成员变量也是有权限的
private:
static int m_other;
};
int Person::m_Age = 0;//类外初始化实现
int Person::m_other = 10;
void test01()
{
//1.通过对象访问属性
Person p1;
p1.m_Age = 10;
Person p2;
p2.m_Age = 20;
cout << "p1.m_Age:" << p1.m_Age << endl;//20
cout << "p2.m_Age:" << p2.m_Age << endl;//20
//2.通过类名访问属性
cout << "通过类名访问m_Age:" << Person::m_Age << endl;
//cout << "通过类名访问m_other:" << Person::m_other << endl;//私有权限在类外无法访问
}
int main(void)
{
test01();
system("pause");
return EXIT_SUCCESS;
}
3.静态成员函数不可以访问普通成员变量
因普通成员变量可以别共享,所以静态成员函数不可以访问普通成员变量。
原理如下:
4.普通成员函数 可以访问普通成员变量,也可以访问静态成员变量
#define _CRT_SECURE_NO_WARNINGS
#include<iostream>
using namespace std;
class Person
{
public:
static int m_Age;//加入static就是 静态成员变量,会共享数据
//静态成员变量,在类内声明,类外进行初始化
int m_A;
//静态成员函数
//静态成员函数不可以访问 普通成员变量
//普通成员函数 可以访问普通成员变量,也可以访问静态成员变量
static void func()
{
//m_A = 10;//不可以访问
m_Age = 10;//可以访问静态成员变量
cout << "静态成员函数 func() 的调用" << endl;
}
//静态成员变量也是有权限的
//静态成员函数也是有权限的
private:
static int m_other;
void func2()
{
}
};
int Person::m_Age = 0;//类外初始化实现
int Person::m_other = 10;
void test01()
{
//1.通过对象访问属性
Person p1;
p1.m_Age = 10;
Person p2;
p2.m_Age = 20;
cout << "p1.m_Age:" << p1.m_Age << endl;//20
cout << "p2.m_Age:" << p2.m_Age << endl;//20
//2.通过类名访问属性
cout << "通过类名访问m_Age:" << Person::m_Age << endl;
//cout << "通过类名访问m_other:" << Person::m_other << endl;//私有权限在类外无法访问
//静态成员函数的调用
p1.func();
p2.func();
Person::func();
//静态成员函数也是有权限的
//Person::func2();
}
int main(void)
{
test01();
system("pause");
return EXIT_SUCCESS;
}
02 单例模式案例-主席案例
构造函数优于main函数调用,static在编译阶段就构造好了,main函数是在运行阶段才调用
#define _CRT_SECURE_NO_WARNINGS
#include<iostream>
using namespace std;
//创建主席类
class ChairMan
{
private:
//构造函数私有化
ChairMan() {
cout << "主席构造函数调用" << endl;
}
public:
static ChairMan* singleMan;
};
ChairMan* ChairMan::singleMan = new ChairMan;
//需求 单例模式 为了创建类中的对象,并且保证只有一个对象实例
void test01()
{
/*ChairMan c1;
ChairMan* c2 = new ChairMan;*/
ChairMan::singleMan;
}
int main(void)
{
cout << "main函数调用" << endl;//主席先于main的调用
test01();
system("pause");
return EXIT_SUCCESS;
}
#define _CRT_SECURE_NO_WARNINGS
#include<iostream>
using namespace std;
//创建主席类
class ChairMan
{
private:
//构造函数私有化
ChairMan() {
cout << "主席构造函数调用" << endl;
}
//拷贝构造函数私有化
ChairMan(const ChairMan& c) {}
public:
//提供get方法访问主席
static ChairMan* getInstance()
{
return singleMan;
}
private:
static ChairMan* singleMan;
};
ChairMan* ChairMan::singleMan = new ChairMan;
//需求 单例模式 为了创建类中的对象,并且保证只有一个对象实例
void test01()
{
/*ChairMan c1;
ChairMan* c2 = new ChairMan;*/
/*ChairMan* cm1 = ChairMan::singleMan;
ChairMan* cm2 = ChairMan::singleMan;*/
//ChairMan::singleMan = NULL;
ChairMan* cm1 = ChairMan::getInstance();
ChairMan* cm2 = ChairMan::getInstance();
if (cm1 == cm2)
{
cout << "cm1和cm2相同" << endl;
}
else
{
cout << "cm1和cm2不相同" << endl;
}
/*ChairMan* cm3 = new ChairMan(*cm1);//构造函数私有化了,不可调用默认构造函数使用值传递,导致不相同
if (cm3 == cm2)
{
cout << "cm3和cm2相同" << endl;
}
else
{
cout << "cm3和cm2不相同" << endl;
}*/
}
int main(void)
{
//cout << "main函数调用" << endl;//主席先于main的调用
test01();
system("pause");
return EXIT_SUCCESS;
}
03 单例模式案例-打印机案例
#define _CRT_SECURE_NO_WARNINGS
#include<iostream>
#include<string>
using namespace std;
class Printer
{
private:
Printer() {//:printCount(0){
//printCount = 0;
}
Printer(const Printer& p) {}
public:
static Printer* getInstance()
{
return singlePrinter;
}
void doPrintText(string text)
{
cout << text << endl;
printCount++;
}
int getPrintCount()
{
return printCount;
}
private:
static Printer* singlePrinter;
static int printCount;
};
Printer* Printer::singlePrinter = new Printer;
int Printer::printCount = 0;
void test01()
{
Printer* printer = Printer::getInstance();
printer->doPrintText("入职报告");
printer->doPrintText("加薪申请");
printer->doPrintText("升级申请");
printer->doPrintText("退休申请");
printer->doPrintText("辞职报告");
cout << "公司打印机使用次数: " << printer->getPrintCount() << endl;
}
int main(void)
{
test01();
system("pause");
return EXIT_SUCCESS;
}
04 C++对象模型初探-成员变量和成员属性分开处理
1.成员变量和成员属性分开存储
2.空类的大小为1,每个实例的对象都有独一无二的地址
#define _CRT_SECURE_NO_WARNINGS
#include<iostream>
using namespace std;
class Person
{
};
void test01()
{
cout << "Person 类的大小: " << sizeof(Person) << endl;
//空类的大小为1,每个实例的对象都有独一无二的地址,char维护这个地址
}
int main(void)
{
test01();
system("pause");
return EXIT_SUCCESS;
}
非静态成员变量。才属于对象身上
#define _CRT_SECURE_NO_WARNINGS
#include<iostream>
using namespace std;
class Person
{
public:
int m_A;//非静态成员变量,属于对象身上
void func() {}//非静态成员函数,不属于对象身上
static int m_B;//静态成员变量,不属于对象身上
static void func2() {};//静态成员变量,不属于对象身上
};
//结论:非静态成员变量。才属于对象身上
void test01()
{
cout << "Person 类的大小: " << sizeof(Person) << endl;
//空类的大小为1,每个实例的对象都有独一无二的地址,char维护这个地址
}
int main(void)
{
test01();
system("pause");
return EXIT_SUCCESS;
}
calss默认对齐,可以用#pragma pack(1)删除
#define _CRT_SECURE_NO_WARNINGS
#include<iostream>
using namespace std;
//#pragma pack(1)
class Person
{
public:
int m_A;//非静态成员变量,属于对象身上
void func() {}//非静态成员函数,不属于对象身上
static int m_B;//静态成员变量,不属于对象身上
static void func2() {};//静态成员变量,不属于对象身上
double m_C;//16
};
//结论:非静态成员变量。才属于对象身上
void test01()
{
cout << "Person 类的大小: " << sizeof(Person) << endl;
//空类的大小为1,每个实例的对象都有独一无二的地址,char维护这个地址
}
int main(void)
{
test01();
system("pause");
return EXIT_SUCCESS;
}
05 this指针基本使用
1.this指针指向被调用的成员函数所属的对象
#define _CRT_SECURE_NO_WARNINGS
#include<iostream>
using namespace std;
//#pragma pack(1)
class Person
{
public:
int m_A;//非静态成员变量,属于对象身上
void func() {}//非静态成员函数,不属于对象身上
static int m_B;//静态成员变量,不属于对象身上
static void func2() {};//静态成员变量,不属于对象身上
double m_C;//16
};
void test02()
{
//this指针指向被调用的成员函数所属的对象
Person p1;
p1.func();//编译器会默认加一个隐含指针 this指针 在这是Person* this
//this指针永远指向当前对象
Person p2;
p2.func();
}
2.this可以解决命名冲突问题
#define _CRT_SECURE_NO_WARNINGS
#include<iostream>
using namespace std;
class Person
{
public:
//this可以解决命名冲突问题
Person(int age)
{
this->age = age;
}
//对比年龄
void compareAge(Person& p)
{
if (this->age == p.age)
{
cout << "年龄相等" << endl;
}
else
{
cout << "年龄不相等" << endl;
}
}
int age;
};
void test01()
{
Person p1(10);
cout << "p1.age = " << p1.age << endl;
Person p2(10);
p1.compareAge(p2);
cout << "p1.age = " << p1.age << endl;
}
int main(void)
{
test01();
system("pause");
return EXIT_SUCCESS;
}
3.*this 链式编程
#define _CRT_SECURE_NO_WARNINGS
#include<iostream>
using namespace std;
class Person
{
public:
//this可以解决命名冲突问题
Person(int age)
{
this->age = age;
}
//对比年龄
void compareAge(Person& p)
{
if (this->age == p.age)
{
cout << "年龄相等" << endl;
}
else
{
cout << "年龄不相等" << endl;
}
}
//年龄相加
Person& plusAge(Person& p)
{
this->age += p.age;
return *this;//this指向对象本体
}
int age;
};
void test01()
{
Person p1(10);
cout << "p1.age = " << p1.age << endl;
Person p2(10);
p1.compareAge(p2);
p1.plusAge(p2).plusAge(p2);//链式编程
cout << "p1.age = " << p1.age << endl;
}
int main(void)
{
test01();
system("pause");
return EXIT_SUCCESS;
}
06 空指针访问成员函数
如果成员函数没有用到this,那么空指针可以直接访问
如果成员函数用到this指针,那么注意,可以加if判断,如果this为NULL就return
#define _CRT_SECURE_NO_WARNINGS
#include<iostream>
using namespace std;
class Person
{
public:
void personShow()
{
cout << "Person_show" << endl;
}
void showAge()
{
if (this == NULL)
{
return;
}
cout << "personAge:" << personAge << endl;
}
int personAge;
};
void test01()
{
Person* p1 = NULL;
p1->personShow();
p1->showAge();
}
int main(void)
{
test01();
system("pause");
return EXIT_SUCCESS;
}
#define _CRT_SECURE_NO_WARNINGS
#include<iostream>
using namespace std;
class Person
{
public:
void personShow()
{
cout << "Person_show" << endl;
}
void showAge()
{
if (this == NULL)
{
return;
}
cout << "personAge:" << personAge << endl;
}
int personAge;
};
void test01()
{
Person* p1 = NULL;
p1->personShow();
p1->showAge();
}
int main(void)
{
test01();
system("pause");
return EXIT_SUCCESS;
}
07 常函数和常对象
常函数,不允许修改this指针指向的值.
常对象,不允许修改属性.
常对象,不可以调用普通成员函数.
常对象,可以调用常函数.
#define _CRT_SECURE_NO_WARNINGS
#include<iostream>
using namespace std;
class Person
{
public:
Person()
{
this->m_A = 0;
this->m_B = 0;
}
void showInfo() const//常函数 不允许修改this指针指向的值
{
//this->m_A = 10;
this->m_B = 10;
cout << "m_A:" << this->m_A << endl;
cout << "m_B:" << this->m_B << endl;
}
int m_A;
mutable int m_B;//就算是常函数,这个变量还是有修改的需求
};
void test01()
{
Person p1;
p1.showInfo();
//常对象 不允许修改属性
const Person p2;
//p2.m_A = 1000;
//常对象 不可以调用普通成员函数
//常对象 可以调用常函数
}
int main(void)
{
test01();
system("pause");
return EXIT_SUCCESS;
}
08 全局函数做友元函数
全局函数写到类中做声明,并且最前面写关键字friend。
友元函数的目的就是访问类中的私有成员属性。
#define _CRT_SECURE_NO_WARNINGS
#include<iostream>
#include<string>
using namespace std;
class Building
{
//将全局函数变为 友元函数
friend void goodGay(Building* building);
public:
Building()
{
this->m_bedRoom = "卧室";
this->m_SittingRoom = "客厅";
}
//客厅 卧室
public:
string m_SittingRoom;
private:
string m_bedRoom;
};
void goodGay(Building* building)
{
cout << "好基友正在访问 " << building->m_SittingRoom << endl;
cout << "好基友正在访问 " << building->m_bedRoom << endl;
}
//友元函数的目的就是 访问类中的私有成员属性
void test01()
{
Building* building = new Building;
goodGay(building);
delete building;
}
int main(void)
{
test01();
system("pause");
return EXIT_SUCCESS;
}
09 类做友元类
友元类注意:
1.友元关系不能被继承
2.友元关系是单向的,类A是类B的朋友,但类B不一定是类A的朋友
3.友元关系不具有传递性。类B是类A的朋友,类C是类B的朋友,但类C不一定是类A的朋友。
#define _CRT_SECURE_NO_WARNINGS
#include<iostream>
#include<string>
using namespace std;
class Building
{
//将全局函数变为 友元函数
friend void goodGay(Building* building);
public:
Building()
{
this->m_bedRoom = "卧室";
this->m_SittingRoom = "客厅";
}
//客厅 卧室
public:
string m_SittingRoom;
private:
string m_bedRoom;
};
void goodGay(Building* building)
{
cout << "好基友正在访问 " << building->m_SittingRoom << endl;
cout << "好基友正在访问 " << building->m_bedRoom << endl;
}
//友元函数的目的就是 访问类中的私有成员属性
void test01()
{
Building* building = new Building;
goodGay(building);
delete building;
}
int main(void)
{
test01();
system("pause");
return EXIT_SUCCESS;
}
10 成员函数做友元函数
#define _CRT_SECURE_NO_WARNINGS
#include<iostream>
using namespace std;
//只让visit可以作为Building的好朋友 ,visit2不可以访问私有成员属性
class Building;
class goodGay
{
public:
goodGay();
void visit();
void visit2();
private:
Building* m_building;
};
class Building
{
//让成员函数 visit作为友元函数
friend void goodGay::visit();
public:
Building();
public:
string m_SittingRoom;
private:
string m_BedRoom;
};
void test01()
{
goodGay gg;
gg.visit();
}
int main(void)
{
test01();
system("pause");
return EXIT_SUCCESS;
}
Building::Building()
{
this->m_BedRoom = "卧室";
this->m_SittingRoom = "客厅";
}
goodGay::goodGay()
{
this->m_building = new Building;
}
void goodGay::visit()
{
cout << "好基友正在访问 " << m_building->m_SittingRoom << endl;
cout << "好基友正在访问 " << m_building->m_BedRoom << endl;
}
void goodGay::visit2()
{
cout << "好基友正在访问 " << m_building->m_SittingRoom << endl;
//cout << "好基友正在访问 " << m_building->m_BedRoom << endl;
}