1. const数据成员:
const类型变量不可以修改,只读模式
const数据成员可以通过初始化参数列表的方式进行初始化
#include<iostream>
#include<string>
using namespace std;
class Fox
{
public:
void printf()
{
cout << name << endl;
}
Fox(string mname):name(mname) //这种方式是正确的,因为在调用构造函数的时候,相当于在创建时初始化数据成员
{
//name = mname;//这种方式是错误的,因为常属性的成员是不可以修改的!
}
protected:
const string name;
};
int main()
{
Fox yueyue("月月");
yueyue.printf();
return 0;
}
const成员函数
const成员函数写法上就算在函数名后面写上const
const成员函数只读数据成员,不能对数据成员进行修改
const同名函数可以和普通同名函数共同存在(我个人认为,这是一种函数重载)
普通对象可以调用常成员函数,但是普通对象优先调用普通成员函数
常对象只能调用常函数,不可以调用普通成员函数
#include<iostream>
#include<string>
using namespace std;
class Fox
{
public:
void printf()const //常成员函数
{
//a = 100;//错误 因为常成员函数只能访问数据成员,不能去修改数据成员
cout << name << endl;
cout << "我是常成员" << endl;
}
void printf() //普通成员函数
{
a = 50;//正确 因为类中无视权限访问
cout << name << endl;
cout << "我不是常成员" << endl;
}
Fox(string mname):name(mname) //这种方式是正确的,因为在调用构造函数的时候,相当于在创建时初始化数据成员
{
//name = mname;//这种方式是错误的,因为常属性的成员是不可以修改的!
}
protected:
const string name;
int a = 0;
};
int main()
{
Fox yueyue("月月");
yueyue.printf();//这里默认调用的是同名的普通成员函数。。如果你把普通成员屏蔽了,普通对象也可以调用常成员函数
const Fox nannan("南南");
nannan.printf();//这里必调用常成员函数,且不能调用普通成员函数
return 0;
}
2.static成员
static不属于对象,属于类,也就意味着所有对象共有,调用是不需要对象,也可以通过对象调用
static数据成员依旧受权限限定。
static成员在类中初始化是错误的,必须在类外初始化, 且在类外初始化时不需要加static修饰
但需要加入类名限定
static成员函数 static写在函数名前面 调用非静态成员,必须类名限定
static对象周期是到程序结束才会死亡
#include<iostream>
#include<string>
using namespace std;
class Fox
{
public:
void printf()
{
cout << num << endl;
}
static void printf(Fox&fox)
{
cout << num << endl;
//cout << age << endl;//错误写法,因为age不是静态成员,需要对象提供访问
cout <<fox.age << endl;//正确写法
}
Fox(int mage)
{
age = mage;
//int Fox::num = 189;
//num = 189; //这两种方式都是错误的,除非已在类外实现的过后,才可以在在类中调用
}
Fox() = default;//说明使用默认构造函数
public:
int age;
static int num;
};
int Fox::num = 100; //类外赋值,且不用加关键字static。不可以在类中赋值 //类外实现num的赋值
//加入类名限定 ,
int main()
{
cout << Fox::num << endl;//不用对象可以直接调用,因为是共有的
Fox HULI(18);
HULI.printf();
Fox yueyue(19);
yueyue.printf();//且它们共享一个static的成员 都会打印100
Fox::printf(yueyue);//调用静态成员函数,需要类名限定
return 0;
}
3.友元函数
友元类型提供一个场所,赋予对象打破类的权限(无视权限限定)
关键字friend,友元不属于类,不能直接访问成员
友元函数在类外实现不需要关键字和类名
VS2019类中实现友元无传参方式函数,应提前声明。
#include<iostream>
#include<string>
using namespace std;
void print();//VS2019类中实现友元无传参方式函数,应提前声明。
class Fox
{
public:
Fox(string name, int age) :name(name), age(age){}
void print()
{
cout << name << "\t" << age << endl;
}
friend void print()
{
//cout << name << endl;//错误写法,友元不属于类不能直接访问成员
Fox yueyue("月月",18);
cout << yueyue.name << "\t" << yueyue.age << endl;//无视权限直接访问
};//用friend 标识为友元
friend void print2(Fox& yueyue);
protected:
string name;
private:
int age;
};
void print2(Fox&yueyue) //友元函数类外实现不需要类名限定和关键字修饰
{
cout << yueyue.name << "\t" << yueyue.age << endl;//类外无视权限直接访问
}
int main()
{
Fox yueyue("月月",5);
yueyue.print();//普通的通过对象去访问类中的数据
print2(yueyue);
print();
}
3.2 以另一个类的成员的函数为友元函数
#include<iostream>
#include<string>
using namespace std;
class B
{
public:
void printf();
private:
};
class A
{
public:
friend void B:: printf();//声明友元函数
private:
int age = 100;
};
void B::printf() //注意顺序,防止未定义问题出现
{
A a;
cout << a.age << endl;
}
//成员函数实现一定是在另一个类的下面实现
int main()
{
B b;
b.printf();
while (1);
return 0;
}
3.3 友元类 互为友元
#include<iostream>
#include<string>
using namespace std;
class Fox
{
public:
Fox() = default;
friend class Fox2;
void printdata();
Fox(string name) :name(name) {};
protected:
string name;
};
class Fox2 //该为Fox的友元类,就算说在Fox2类中 只要是Fox的对象都无视权限直接访问
{
public:
Fox2() = default;
friend class Fox;//互为友元
void printFox()
{
Fox yueyue("月月");
Fox yueyue1("月月1");
Fox yueyue2("月月2");
cout << yueyue.name << endl;
cout << yueyue1.name << endl;
cout << yueyue2.name << endl;
}
Fox2(string name) :name(name) {};
Fox& returFox(Fox&fox)
{
return fox;
}
protected:
string name;
};
void Fox::printdata() //防止出现未定义问题,实现在另外一个类下面
{
Fox2 yueyue("月月");
Fox2 yueyue1("月月1");
Fox2 yueyue2("月月2");
cout << yueyue.name << endl;
cout << yueyue1.name << endl;
cout << yueyue2.name << endl;
}
int main()
{
Fox2 B;
Fox AA;
AA.printdata();
B.printFox();
return 0;
}
4.this指针和explicit修饰构造词
explicit修饰构造函数,不然构造函数做隐式转换
#include<iostream>
#include<string>
using namespace std;
class Fox
{
public:
explicit Fox(string name) :name(name) {};//进行explicit修饰
protected:
string name;
};
int main()
{
//Fox yueyue = "123";//错误 进行explicit修饰 赋值这种隐式构造不可用//
Fox yueyue{ "123" };//正确
}
this 指针
作用是普通成员函数出现同名参数的时候,普通成员是没法初始化参数列表的
可以利用this 帮助计算机区分
#include<iostream>
#include<string>
using namespace std;
class Fox
{
public:
void ininset(string name,int data)
{ //类名限定
Fox::name = name;
//data = data;//这样子计算机是没办法区分
this->data = data;//利用list指针
}
void print()
{
cout << this->data << this->name << endl;
}
protected:
string name;
int data;
};
int main()
{
Fox yueyue;
yueyue.ininset("月月",18);
yueyue.print();
}
list指针通指对象本身的地址
充当函数返回值,返回对象本身 在类中很难描述对象本身,通过list指针可以得到对象本身
静态成员不能使用this指针 ,this指针不能在类外使用
静态成员函数是不需要对象的 所以list指针无法作用静态成员
#include<iostream>
#include<string>
using namespace std;
class Fox
{
public:
void ininset(string name,int data)
{ //类名限定
Fox::name = name;
//data = data;//这样子计算机是没办法区分
this->data = data;//利用list指针
}
void print()
{
cout << this->data << this->name << endl;
}
void printf()
{
cout << this << endl;//输出this值
}
Fox returnFox()//用于函数的放回置
{
return *this;//返回自身
}
static void printstatic()
{
cout << this->name << cout << this->data;//静态成员无法使用this指针
}
protected:
string name;
int data;
};
int main()
{
Fox yueyue;
yueyue.ininset("月月",18);
yueyue.print();
cout << &yueyue << endl;
yueyue.printf();//我们会发现 取地址和输出this的值都是一样的通指调用对象本身的地址
yueyue.returnFox().returnFox().returnFox();//语法上无问题,返回对象本身,对象访问成员,在返回对象
}