C++(三)
static
c语言的static
C语言中static的作用:
1.static修饰的局部变量,延长生命周期,只初始化一次
2.static修饰全局变量(函数),限制了作用域,只能在本文件内使用
c++中的static
static修饰的成员变量
作用:实现成员变量在类中所有的对象之间的 共享
- 在类内进行声明,类外初始化
- 初始化的格式
数据类型 类名::变量名 = 初始值;
-== 类中的静态成员变量,不属于某个对象,而是属于类,但是每一个对象都可以访问==
- 访问
1、对象.成员变量
2、指针对象名->成员变量
3、类名::成员变量(需要将该成员变量放在public区)
- static修饰的成员没有对象的时候,也可以访问
- 当类中的数据成员的值在其他的类中要使用时,就用static修饰,不用创建对象就可以快速使用!
#include <iostream>
using namespace std;
/*
* static修饰的成员变量
* 作用:实现成员变量在类中所有对象之间共享
* 1.在类内声明,类外初始化
* 2.初始化格式:类型名 类名::变量名 = 初始值;
* 3.类中的成员变量,不属于某个对象,而属于类,但所有对象都可以访问
* 4.访问:对象.成员变量;指针对象名->成员变量;类名::成员变量
*/
class Student
{
public:
//构造
Student(string name = "张三");
//析构
~Student();
void show();
private:
static int count; //类内声明,类外初始化
int id;
string name;
protected:
};
Student::Student(string name)
{
//访问
this->id = Student::count++;
this->name = name;
cout << "**构造**" << endl;
}
Student::~Student()
{
cout << "**析构**" << endl;
}
void Student::show()
{
cout << "学号:" << this->id << ","
<< "姓名" << this->name << endl;
}
//初始化格式:类型名 类名::变量名 = 初始值;
int Student::count = 1;
int main()
{
//创建两个对象,看id是否自增
Student student1("李四");
student1.show();
Student student2("王五");
student2.show();
}
static 修饰成员函数
作用:实现成员函数的共享
- 当该类中的成员函数需要在其他类中使用,此时重新new对象开销大,就可以将该成员函数设置为static
- 静态成员函数没有this指针
- 静态成员函数中不能访问非静态成员(成员变量、成员函数)
- 非静态成员函数可以访问静态成员
- static修饰的成员函数属于类,但是对象可以去调用
- 访问
1、对象.成员函数
2、指针对象->成员函数
3、类::成员函数
#include <iostream>
using namespace std;
/*
* static修饰的成员函数
* 作用:实现成员函数的共享
* 静态成员函数没有this指针
* 静态成员函数不能访问非静态成员
* 非静态成员函数可以访问静态成员
* 静态成员的访问:对象名.静态函数;指针对象->静态函数;类::静态函数
*/
class Student
{
public:
//构造
Student(string name= "张三");
//析构
~Student();
static void show(Student &demo);
void show_name();
private:
static int count;
int id;
string name;
protected:
};
Student::Student(string name)
{
this->id = Student::count++;
this->name = name;
cout << "构造" << endl;
}
Student::~Student()
{
cout << "析构" << endl;
}
void Student::show(Student &demo)
{
//静态成员函数中不存在指针this
/*cout << "学号:" << this->id << ","
<< "姓名:" << this->name << endl;*/
/*静态成员函数不能访问非静态成员
show_name();*/
//传入对象引用来实现输出
cout << "学号:" << demo.id << ","
<< "姓名:" << demo.name << endl;
}
void Student::show_name()
{
//非静态成员函数可以访问静态成员
cout << "变量:" << Student::count << endl;
cout << "姓名:" << this->name << endl;
}
int Student::count = 1;
int main()
{
Student student1("李四");
student1.show(student1);
student1.show_name();
Student student2("王五");
student2.show(student2);
student2.show_name();
}
const
c语言
在C语言中:
const:修饰的只能读不能写
const int a;//栈区
int *p = NULL;
指针常量:int * const p = NULL;//p的指向不能修改
常量指针:int const *p = NULL;//值不能修改
const int const *p = NULL;//值和指向都不能修改
c++
const修饰成员变量
-
const修饰的成员变量只能以初始化列表的形式进行初始化
-
非const修饰的成员变量也可以以初始化列表的方式进行初始化
-
const修饰的成员变量只能读不能修改
#include <iostream>
using namespace std;
/** const 修饰成员变量
* const修饰的成员变量只能以初始化列表的形式初始化
* 非const修饰的成员变量也可以用初始化列表的形式初始化
* const修饰的成员变量只能读不能修改
*/
class Student
{
public:
//构造
Student(int id = 1, string name = "张三", string sex = "女");
//析构
~Student();
void show();
void set_id(int id);
private:
const int id;
string name;
string sex;
protected:
};
Student::Student(int id, string name, string sex):id(id),sex(sex)//非const修饰的成员变量也可以以初始化列表的形式初始化
{
/*const 修饰的成员变量必须以初始化列表的形式初始化 this->id = id;*/
this->name = name;
cout << "构造" << endl;
}
Student::~Student()
{
cout << "析构" << endl;
}
void Student::show()
{
cout << "学号:" << this->id << ","
<< "姓名:" << this->name <<","
<< "性别:" << this->sex << endl;
}
void Student::set_id(int id)
{
/*const 修饰的成员变量不能修改 this->id = id;*/
}
int main()
{
Student student1;
student1.show();
Student student2(2, "李四", "男");
student2.show();
}
const修饰的成员函数
- 本质:const修饰的成员函数本质上是修饰成员函数中的第一个隐藏参数this指针
void Student::set_address(string address)
//Student * const this
{
}
void Student::set_address(string address) const
//const Student * const this
{
}
- const修饰的成员函数中,成员变量的值不能修改
- 互为重载
- 非const修饰的成员函数可以访问const修饰的成员
- const修饰的成员函数不可以访问非const修饰的成员函数
#include <iostream>
using namespace std;
/*
* const 修饰成员函数实质上修饰的是成员函数第一个参数this
* const 修饰的成员函数不可以修改成员变量
* const 修饰的成员函数不可以访问非const修饰的成员函数
* 非const 修饰的成员函数可以访问const修饰的成员
* const 修饰的成员函数与非const修饰的成员函数互为重载
*/
class Student
{
public:
Student(int id = 1, string name = "张三", string sex = "女");
~Student();
void show();
void set_name(string name) const;
void set_name(string name);
void show_name() const;
private:
const int id;
string name;
string sex;
protected:
};
Student::Student(int id, string name, string sex) :id(id), sex(sex)
{
this->name = name;
cout << "构造" << endl;
}
Student::~Student()
{
cout << "析构" << endl;
}
void Student::show()
{
this->show_name();
cout << "学号:" << this->id << "," //非const修饰的成员函数可以访问const修饰的成员
<< "姓名:" << this->name << ","
<< "性别:" << this->sex << endl;
}
void Student::set_name(string name) const //const Studnet * const this;指向和值都不可改变
{
/*const修饰的成员函数不可以修改成员变量
this->name = name;*/
//const修饰的成员函数可以访问非const修饰的成员变量
cout << this->name << endl;
/*const 修饰的成员函数不可以访问非const修饰的成员函数
this.show();*/
}
void Student::set_name(string name)//Student * const this;const修饰的成员函数与非const修饰的成员函数互为重载
{
this->name = name;
}
void Student::show_name() const
{
cout << this->name << endl;
}
int main()
{
Student student1(2, "李四", "男");
student1.show();
}
const修饰的类对象
- const修饰类对象之后只能访问const修饰的函数
#include <iostream>
using namespace std;
/*
* const 修饰的类对象
* 只能访问const修饰的成员函数
*/
class Student
{
public:
Student(int id = 1, string name = "张三");
~Student();
void show() const;
void set_name(string name);
private:
const int id;
string name;
protected:
};
Student::Student(int id, string name):id(id)
{
this->name = name;
cout << "构造" << endl;
}
Student::~Student()
{
cout << "析构" << endl;
}
void Student::show() const
{
cout << "学号:" << this->id << ","
<< "姓名:" << this->name << endl;
}
void Student::set_name(string name)
{
this->name = name;
}
int main()
{
const Student student1;
student1.show();
/*const 修饰的类对象,类对象不能访问const修饰的成员变量
cout << student1.id << endl;*/
/*const 修饰的类对象,类对象只能访问const修饰的成员函数
student1.set_name();*/
return 0;
}
mutable
- 打破了const的限制
- const修饰的成员函数中,成员变量的值不能被修改
- 一般情况下不要使用,除非破不得已
#include <iostream>
using namespace std;
/*
* mutable 打破const
* 使得const修饰的成员函数可以修改mutable修饰的成员变量
*/
class Student
{
public:
Student(int id = 1, string name = "张三");
~Student();
void show();
void set_name(string name) const;
private:
const int id;
mutable string name;
protected:
};
Student::Student(int id, string name) :id(id)
{
this->name = name;
cout << "构造" << endl;
}
Student::~Student()
{
cout << "析构" << endl;
}
void Student::show()
{
cout << "学号:" << this->id << ","
<< "姓名:" << this->name << endl;
}
void Student::set_name(string name) const
{
//const 修饰的函数可以修改mutable修饰的成员变量
this->name = name;
}
int main()
{
Student student1;
student1.show();
student1.set_name("李四");
student1.show();
return 0;
}
友元
- 友元打破了private、protected的限制
- 私有的(受保护的)成员变量要访问在public区提供函数接口去访问的;如果访问的次数少,没有关系;如果访问的比较频繁,对系统消耗比较多;如果能直接访问的话大大提高了效率
- 关键字:friend
普通函数作为友元
#include <iostream>
using namespace std;
/*
* 友元 打破private,protected
* 普通函数作为友元函数:使得普通函数可以操作类中的私有成员变量
*/
class Student
{
public:
Student(int id = 1, string name = "张三");
~Student();
void show();
friend void set_get_name(Student &denmo, string name);
private:
int id;
string name;
protected:
};
Student::Student(int id, string name) :id(id)
{
this->name = name;
cout << "构造" << endl;
}
Student::~Student()
{
cout << "析构" << endl;
}
void Student::show()
{
cout << "学号:" << this->id << ","
<< "姓名:" << this->name << endl;
}
void set_get_name(Student &demo, string name)
{
cout << "原始name:" << demo.name << endl;
demo.name = name;
cout << "修改后name:" << demo.name << endl;
}
int main()
{
Student student1;
set_get_name(student1, "王五");
return 0;
}
类的成员函数作为友元
问题
解决:在类内声明,类外定义
#include <iostream>
using namespace std;
/*
* 友元 打破private,protected
* 类的成员函数作为友元函数:使得类的成员函数可以操作类中的私有成员变量
* 先声明,在类外定义
*/
class Student;
class Tea
{
public:
void set_get_name(Student& demo, string name);
private:
protected:
};
class Student
{
public:
Student(int id = 1, string name = "张三");
~Student();
void show();
friend void Tea::set_get_name(Student& denmo, string name);
private:
int id;
string name;
protected:
};
Student::Student(int id, string name) :id(id)
{
this->name = name;
cout << "构造" << endl;
}
Student::~Student()
{
cout << "析构" << endl;
}
void Student::show()
{
cout << "学号:" << this->id << ","
<< "姓名:" << this->name << endl;
}
void Tea::set_get_name(Student& demo, string name)
{
cout << "原始name:" << demo.name << endl;
demo.name = name;
cout << "修改后name:" << demo.name << endl;
}
int main()
{
Student student1;
Tea tea;
tea.set_get_name(student1, "王五");
return 0;
}
友元类
- 当A类中有多个成员函数要访问B类中的私有成员变量时
#include <iostream>
using namespace std;
/*
* 友元 打破private,protected
* 类的成员函数作为友元函数:使得类的成员函数可以操作类中的私有成员变量
* 先声明,在类外定义
*/
class Student;
class Tea
{
public:
void set_get_name(Student& demo, string name);
void get_id(Student& demo);
private:
protected:
};
class Student
{
public:
Student(int id = 1, string name = "张三");
~Student();
void show();
friend class Tea;
private:
int id;
string name;
protected:
};
Student::Student(int id, string name) :id(id)
{
this->name = name;
cout << "构造" << endl;
}
Student::~Student()
{
cout << "析构" << endl;
}
void Student::show()
{
cout << "学号:" << this->id << ","
<< "姓名:" << this->name << endl;
}
void Tea::set_get_name(Student& demo, string name)
{
cout << "原始name:" << demo.name << endl;
demo.name = name;
cout << "修改后name:" << demo.name << endl;
}
void Tea::get_id(Student& demo)
{
cout << "id:" << demo.id << endl;
}
int main()
{
Student student1;
Tea tea;
tea.set_get_name(student1, "王五");
tea.get_id(student1);
return 0;
}