小知识,大挑战!本文正在参与“程序员必备小知识”创作活动。
一、常函数(常成员函数)和常对象
1.1 常函数
- 常函数,也就是常成员函数
- 在函数名参数最==右边加const==
- 调用常成员函数和普通成员函数一样,不需要加 const
- 常函数无法修改普通成员变量的值,只能获取值,==只能读不能写==(通俗的讲,把一个函数设置成为常函数,就是不想去设置值,只是区获取值)
- 如果一个成员函数只是获取成员变量的值,可以将这个函数设置为常函数
- 如果要对指定的成员变量执行写操作,则需要使用
mutable
修饰这个成员变量,mutable
关键字修饰的成员变量可以在常成员函数中被修改 - 常成员函数可以重载 (常函数版本和非常函数版本可以构成重载关系)
- 非常对象,优先调用普通的成员函数,如果没有,调用常函数版本
1.2 常对象
- 使用
const
修饰的对象称之为常对象 - 常对象是可以正常调用构造函数
- ==常对象无法操作普通成员函数,只能调用常函数==
- 常对象只能操作公有的被
mutable
修饰的成员变量
#include <iostream>
using namespace std;
class Myclass
{
public:
Myclass(){cout << "无参构造函数" << endl;}
Myclass(int a, int b, int c):a(a),b(b),c(c)
{
cout << "有参构造函数" << endl;
}
void ConstFun()const
{
//this->a = 100;
this->b = 200;
//this->c = 300;
this->d = 400;
cout << this->a << ", ";
cout << this->b << ", ";
cout << this->c << ", ";
cout << this->d << endl;
}
void printMsg()
{
cout << this->a << ", ";
cout << this->b << ", ";
cout << this->c << ", ";
cout << this->d << endl;
}
int a = 0;
mutable int b = 0;
private:
int c = 0;
mutable int d = 0;
};
void test1()
{
Myclass m;
m.ConstFun();
}
void test2()
{
const Myclass m1;
const Myclass m2(333, 666, 888);
//m2.printMsg();
m2.ConstFun();
//m2.a = 123;
m2.b = 234;
//m2.c = 345;
//m2.d = 456;
}
int main()
{
test2();
return 0;
}
二、静态成员变量和静态成员函数
2.1 静态成员函数
- 静态成员函数就是用
static
修饰的成员函数 - ==静态成员函数内没有this指针==,所以只能访问静态成员变量,不能访问普通成员变量
- 静态成员函数内无法操作普通成员变量
- 静态成员函数只能操作静态成员变量
- 静态成员函数属于类,而不属于对象,所以==可以通过类名直接调用==,普通成员函数无法通过类直接调用。
- 静态成员函数属于整个类
Team t1("张三");
t1.show_flag();//静态成员函数的访问方法1 :通过类对象进行访问
Team::show_flag();//静态成员函数的访问方法2 :通过类名直接访问
2.2 静态成员变量
-
静态成员变量操作之前必须要在**==类外初始化==**,否则报错
初始化格式:eg:
int Myclass::a = 0;
-
静态成员变量不属于某一个对象,而是属于类,所以操作静态成员变量,一般通过类名结合域解析符来操作
-
静态成员变量属于整个类,并不是属于某个类对象,被所有的类对象共享,一个类对象对其进行了修改,所有的类对象中该成员变量都会变成新的值
#include <iostream>
using namespace std;
class Myclass{
public:
Myclass()
{
cout << "无参构造函数" << endl;
}
Myclass(int a, int b)
{
cout << "有参构造函数" << endl;
this->a = a;
this->b = b;
}
void printMsg()
{
cout << this->a << ", " << this->b << endl;
}
//静态成员函数
// 静态成员函数就是用static修饰的成员函数
// 静态成员函数内没有this指针
// 静态成员函数内无法操作普通成员变量
// 静态成员函数只能操作静态成员变量
// 静态成员函数属于类,而不属于对象,所以可以通过类名直接调用
static void StaticFun()
{
Myclass::a = 100;
Myclass::b = 200;
//c = 300;
//d = 400;
cout << Myclass::a << ", " << Myclass::b << endl;
//cout << c << ", " << d << endl;
}
//静态成员变量
// 静态成员变量操作之前必须要在类外初始化,否则报错
// 静态成员变量不属于某一个对象,而是属于类,所以操作静态成员变量,一般通过类名结合域解析符来操作
static int a;
int c;
private:
static int b;
int d;
};
//静态成员变量都要在类外初始化
int Myclass::a = 0;
int Myclass::b = 0;
void test1()
{
Myclass m1;
Myclass m2(100, 200);
m2.printMsg();
m2.a = 888;
cout << "m2.a = " << m2.a << endl;
Myclass m3;
cout << "m3.a = " << m3.a << endl;
cout << Myclass::a << endl;
Myclass::a = 111;
cout << "m2.a = " << m2.a << endl;
}
void test2()
{
Myclass m1;
m1.StaticFun();
//静态成员函数属于类,所以可以让类直接调用
Myclass::StaticFun();
//普通成员函数无法通过类直接调用
//Myclass::printMsg();
}
int main()
{
test2();
return 0;
}
📝练习:判断当前类实例化了多少个对象
#include <iostream>
using namespace std;
class Myclass{
public:
Myclass()
{
Myclass::num++;
}
~Myclass()
{
Myclass::num--;
}
Myclass(const Myclass &obj)
{
Myclass::num++;
}
static int num;
};
int Myclass::num = 0;
void test1()
{
Myclass m1;
Myclass m2;
cout << __LINE__ << "行的对象的个数是:" << Myclass::num << endl;
//代码块:拥有独立的空间,执行结束后空间释放,
//代码块前面的程序的数据可以在内部操作
{
Myclass m3;
Myclass m4;
cout << __LINE__ << "行的对象的个数是:" << Myclass::num << endl;
}
cout << __LINE__ << "行的对象的个数是:" << Myclass::num << endl;
Myclass m5 = m1;
cout << __LINE__ << "行的对象的个数是:" << Myclass::num << endl;
}
int main()
{
test1();
cout << __LINE__ << "行的对象的个数是:" << Myclass::num << endl;
Myclass m6;
Myclass m7;
cout << __LINE__ << "行的对象的个数是:" << Myclass::num << endl;
return 0;
}
执行结果:
三、友元
友元:是另外一种操作类内私有成员的方法
分类:
- 友元函数(友元全局函数)
- 友元类
- 友元成员(友元成员函数)
📣注意:
- 1.友元不具有双向性;//A是B的朋友,B不一定是A的朋友
- 2.友元不具有传递性;//A是B的朋友,B是C的朋友,A不一定是C的朋友
- 3.友元关系不能被继承; //父类的朋友不一定是子类的朋友
7.1 友元函数
将一个全局函数设置为友元,称之为友元函数,友元函数内部可以对类中的所有成员进行操作。
友元函数:
- 将全局函数在类中使用friend声明,那么这个函数为友元函数
- 友元函数可以操作类中的任意成员
#include <iostream>
using namespace std;
class Dc21071{
friend void zhangsan();
public:
string name;
char sex;
string phone;
private:
string sid;
string address;
bool bgfriend;
};
void zhangsan()
{
Dc21071 xiaoli;
xiaoli.name = "小丽";
xiaoli.sex = 'M';
xiaoli.phone = "18888888888";
xiaoli.sid = "11019999999999";
xiaoli.address = "北京明园大学";
xiaoli.bgfriend = true;
cout << xiaoli.name << ", ";
cout << xiaoli.sex << ", ";
cout << xiaoli.phone << ", ";
cout << xiaoli.sid << ", ";
cout << xiaoli.address << ", ";
cout << xiaoli.bgfriend << endl;
}
int main()
{
zhangsan();
return 0;
}
7.2 友元类
友元类:
- 将类a作为类b的友元,将a称之为友元类
- 类a中的所有成员函数内都可以操作类b中的任意成员
#include <iostream>
using namespace std;
class Dc21071{
friend class banzhuren;
public:
string name;
char sex;
string phone;
private:
string sid;
string address;
bool bgfriend;
};
class banzhuren{
public:
void xiaoli()
{
Dc21071 xiaoli;
xiaoli.name = "小丽";
xiaoli.sex = 'M';
xiaoli.phone = "18888888888";
xiaoli.sid = "11019999999999";
xiaoli.address = "北京明园大学";
xiaoli.bgfriend = true;
cout << xiaoli.name << ", ";
cout << xiaoli.sex << ", ";
cout << xiaoli.phone << ", ";
cout << xiaoli.sid << ", ";
cout << xiaoli.address << ", ";
cout << xiaoli.bgfriend << endl;
}
void wangli()
{
Dc21071 xiaoli;
xiaoli.name = "小丽";
xiaoli.sex = 'M';
xiaoli.phone = "18888888888";
xiaoli.sid = "11019999999999";
xiaoli.address = "北京明园大学";
xiaoli.bgfriend = true;
cout << xiaoli.name << ", ";
cout << xiaoli.sex << ", ";
cout << xiaoli.phone << ", ";
cout << xiaoli.sid << ", ";
cout << xiaoli.address << ", ";
cout << xiaoli.bgfriend << endl;
}
};
int main()
{
banzhuren shanshan;
shanshan.xiaoli();
shanshan.wangli();
// banzhuren jiaojiao;
// jiaojiao.zhangli.address = "北京";
return 0;
}
7.3 友元成员
友元成员:
- 将一个类的某一个成员函数作为另一个类的友元,称之为友元成员
- 这个友元成员函数内部可以操作那个类的任意成员,但是其他成员函数不能操作
必须按照顺序设置,不然会报错:
- 第一步:声明要设置友元的类
- 第二步:先定义要设置的友元成员所在的类
- 第三步:声明要设置友元成员的成员函数
- 第四步:定义要设置友元的类
- 第五步:声明要设置友元成员的成员函数
- 第六步:友元成员函数类外实现
#include <iostream>
using namespace std;
//第一步:声明要设置友元的类
class Dc21071;
//第二步:先定义要设置的友元成员所在的类
class banzhuren{
public:
//第三步:声明要设置友元成员的成员函数
void shanshan();
};
//第四步:定义要设置友元的类
class Dc21071{
//第五步:声明要设置友元成员的成员函数
friend void banzhuren::shanshan();
public:
string name;
char sex;
string phone;
private:
string sid;
string address;
bool bgfriend;
};
//第六步:友元成员函数类外实现
void banzhuren::shanshan()
{
Dc21071 xiaoli;
xiaoli.name = "小丽";
xiaoli.sex = 'M';
xiaoli.phone = "18888888888";
xiaoli.sid = "11019999999999";
xiaoli.address = "北京明园大学";
xiaoli.bgfriend = true;
cout << xiaoli.name << ", ";
cout << xiaoli.sex << ", ";
cout << xiaoli.phone << ", ";
cout << xiaoli.sid << ", ";
cout << xiaoli.address << ", ";
cout << xiaoli.bgfriend << endl;
}
int main()
{
banzhuren b;
b.shanshan();
//b.jiaojiao();
return 0;
}