静态常量友元
- 静态成员
- 常量成员
- 友元成员
静态成员
什么是静态成员
静态成员, 指的是在C++类中声明成员时可以加上static关键字, 这样声明的成员就叫静态成员
静态成员的组成
- 静态数据成员
- 静态成员函数
class CBaseBitmap
{
public:
static int num; //静态数据成员
static int GetNum() {return num;} //静态成员函数
};
静态数据成员
- 类中静态数据成员, 所有对象都共享该数据, 只有一份存在内存中
- 类中的静态成员(不管私有还是共有), 必须类外初始化, 因为它不属于对象, 属于类, 对象存在还是不存在这个静态数据成员都是存在的, 静态数据成员的生命周期是程序开始就存在的, 直到程序结束才会被释放
- 类中的静态数据成员, 可以被重新赋值, 可以被普通函数访问, 该改成如果是公有属性, 就还可以被类名或对象点出来直接只用
类名::静态数据成员; //通过作用域运算符::访问
对象.静态数据成员; //通过 . 点运算符访问
静态数据成员操作示例
class CBaseBitmap
{
public:
static int num; //静态数据成员声明
}myBitmap;
int CBaseBitmap::num = 0; //静态数据成员定义
//通过类名直接访问
cout << CBaseBitmap::num << endl;
//通过对象名访问
cout << myBitmap.num << endl;
静态成员函数
- 类中的静态函数成员, 因为这个函数也不属于对象, 所以在这个函数中不能操作类中普通数据成员和普通成员函数
- 类中的静态成员函数(不管私有还是私有), 可以在类外定义, 也可以在类中定义
class CTest
{
public:
static void myTest1(){} //在类中进行定义
static void myTest2(); //在类中进行声明
}myTest;
void CTest::myTest2(){} //在类外进行定义
类中的静态函数成员访问。
类中静态函数成员的访问与类中静态数据成员访问一致。
//通过类名直接访问
CTest::myTest1();
//通过对象名访问
myTest.myTest2();
单例模式
单例模式,是一种常用的软件设计模式。通过单例模式可以保证系统中,应用该模式的类只有一个实例。
单例模式的类中只提供私有的构造函数。
包含一个类的私有静态对象
提供一个静态的公有函数去创建或获取它本身的静态私有对象。
练习代码
#define _CRT_SECURE_NO_WARNINGS
#include<iostream>
using namespace std;
//单例模式 (饿汉模式, 懒汉模式)
//单例模式的类中只提供私有的构造函数
//包含一个类的私有静态对象
//提供一个静态的公有函数去创建或者去获取它本身的静态私有对象
//饿汉模式
class Person
{
static Person* p;
//防止拷贝
Person(const Person&p){}
Person()
{
cout << "无参构造" << endl;
}
public:
void fun()
{
cout << "单例模式" << endl;
}
static Person* getP()
{
return p;
}
};
Person* Person::p = new Person;//初始化的时候new个对象就是饿汉模式
int main()
{
Person* p = Person::getP();
p->fun();
delete p;
p = NULL;
system("pause");
return 0;
}
常量成员
什么是常量成员?
常量成员,指的是在C++类中声明成员时可以加上const关键字,这样声明的成员就叫常量成员。
常量成员的组成
- 常量数据成员
- 常量成员函数
class CNpc
{
const int id; //常量数据成员
int hp;
public:
int GetNpcHp() const {return hp;} //常量成员函数
};
常量数据成员
类中成员数据前面加上const修饰,该数据为常量。
通过成员初始化列表进行赋值。
常量成员函数
- 类中成员函数后面加上const修饰,该函数为常量,可以在类内或类外定义。
- 类中的常量函数成员,这个函数不能对自身变量进行修改。
通过语法限定,只要是this指针所指向的所有数据,在这个函数里面都不可以
被修改,可以帮助我们来限定去修改调用者自身的数据。
常量对象
- 类对象前面加上const修饰,该对象为常量,满足常量的操作,声明时必须初始化。
- 该对象里面所有的成员数据都不能被修改。因此该对象里面的普通成员函数将不允许被调用,只允许调用常量成员函数。
注意, 静态成员都不属于对象
友元成员
什么是友元?
类的特性之一是封装,友元就是C++为用户提供打破这种封装(数据隐藏)的手段。
友元分为:
- 友元函数
- 友元类
友元函数
友元函数,不管这个函数在类中还是类外定义,它只是一个函数,它不是类的成员,通过类对象是无法访问的。但在这个函数中有权直接访问类中的所有成员,包括私有成员。
//该函数不是类中成员,所以类中访问属性不会影响。
class CMyObject
{
int val;
friend void fun(CMyObject *pMyObj); //友元函数
};
void fun(CMyObject *pMyObj)
{
pMyObj->val = 100;
}
友元类
友元类是一个单独的类。在类中声明该友元类,该友元类中的所有成员函数都可以访问类中的所有成员。
class CMyObject
{
int val;
friend class CMyFriendClass; //友元类
};
class CMyFriendClass
{
public:
void fun(CMyObject *pMyObj)
{
pMyObj->val = 200;
}
};
友元的特性
- 单方向:B是A的朋友,B可以访问A的数据,A不可以访问B的数据。
- 不传递:A是B的朋友,B是C的朋友,A和C没有朋友关系。
- 不继承:A是B的朋友,B是C的父亲,A和C没有关系。
练习代码
#define _CRT_SECURE_NO_WARNINGS
#include<iostream>
#include<string>
using namespace std;
//静态成员
class Person
{
//类中静态数据成员,所有对象都共享改数据, 只有一份存在内存中
//必须类外初始化,它不属于对象, 属于类
static int id;
string name;
public:
Person(string name)
{
this->name = name;
id ++;
}
//没有实例化对象也可以调用
static int Getid()
{
return id;
}
int getid()
{
return id;
}
~Person()
{
}
};
//必须类外初始化,它不属于对象, 属于类
int Person::id = 0;
//常量成员
class Student
{
//常量成员
const int id;
int hp;
public:
Student(int hp) :id(10)
{
this->hp = hp;
cout << "默认构造" << endl;
}
//常量函数成员,在函数后面加上const修饰, 在前面加const修饰的是返回值
//不能修改对象中数据
int GetNpHp() const
{
return hp;
}
void fun()
{
cout << "fun()函数" << endl;
}
friend void fun(Student* p);
friend class A;
};
void fun(Student* p)
{
cout << p->id<<endl<< p->hp << endl;
}
//可以在类内访问类的私有成员
class A
{
Student t;
public:
void fun()
{
cout << t.id << endl;
}
};
//友元成员
int main()
{
/*Person p("小叶");
Person p1("小叶");
Person p2("小叶");
Person p3("小叶");
Person p4("小叶");
cout << p1.getid() << endl;*/
//Person::Getid();
Student s(10);
//只可以调用常量函数成员
const Student stu(10);
stu.GetNpHp();
s.fun();
fun(&s);
system("pause");
return 0;
}