目录
一:this指针
1.类和对象在内存中的关系 this指针
2.类的静态成员:static修饰的数据成员和成员函数
3.类对象的定义:指针,普通对象,对象数组
4.类对象作为函数参数传递的方式:按引用传递
5.const常量 修饰的对象的使用,需要mutable的存取权限
this指针 小结
有使用到数据成员的都要使用this指针,写法为:this->数据成员 (所有的数据成员)
1.每个对象都拥有一份属性,属性值不同,但是成员函数是所有对象所共用的
2.一个类的不同对象响应相同的信息时,调用的是同一个函数,就需要使用到this指针,隐式传参,如不同控件显示的show函数
3.当数据成员与函数形参的名称相同的时候,就需要使用到this指针区分
4.this指针指代自身,可以作为返回值
二:类和对象
类和对象
每个对象成员属性各不相同,但成员方法共用
this指针:每个对象都有一个指向自身的this指针
this隐藏参数:标识每一个对象的不同
this指针隐藏参数:区别每一个调用公共方法(函数)的对象
类[数据类型] 对象[变量]
三:静态static
类的数据成员和成员函数都可以声明为static (类的静态成员static)
静态数据成员可以解决数据共享的问题
之前在C语言中引用全局变量实现共享,现在不使用,因为全局变量有局限性,会破坏类的完整性
类的非静态成员函数可以访问类的静态成员属性
1.static 修饰数据成员 实现数据共享
static修饰 独立于对象,存在在类当中
访问方式: 类名::静态成员变量名
对象.静态成员变量名
static修饰数据成员属性,声明的时候放在public公有访问权限中 示例如下
CStaff.h:
#ifndef CSTAFF_H
#define CSTAFF_H
class Staff
{
public:
Staff();
Staff(int id,char *name,char *pwd,int prole);
~Staff();
static int num;//静态数据成员 放在公有的
private:
int ID;
char name[20];
char pwd[20];
int role;
protected:
};
#endif
CStaff.cpp:
#include"CStaff.h"
#include<iostream>
using namespace std;
//不存在对象当中 是所有对象都能够公共访问的
//独立于对象 存在在类当中的
int Staff::num = 1000;//静态成员的初始化
Staff::Staff()
{
Staff::num++;
}
Staff::Staff(int id,char *name,char *pwd,int prole)
{
this->ID = id;
strcpy(this->name,name);
strcpy(this->pwd,pwd);
this->role = prole;
Staff::num++;
}
Staff::~Staff()
{
}
main.cpp:
#include<iostream>
using namespace std;
#include"CStaff.h"
int main()
{
//静态成员放在public声明
//静态成员所有对象共享,属于类
//静态成员不属于任何一个对象
Staff s1(1001,"lily","123456",1);
// 类名::静态成员变量名
cout<<"num = "<<Staff::num<<endl;//num = 1001
// 对象.静态成员变量名
cout<<"num = "<<s1.num<<endl; //num = 1001
Staff s2(1002,"admin","123456",2);// num = 1002
cout<<"num = "<<s2.num<<endl;
return 0;
}
2.static 修饰成员函数 独立于对象 属于类
优势:可以直接 类::静态函数名() 调用类的所有方法 【 如 Ctools(不用对象 可以直接通过类名 域运算符 函数名就能访问 工具类的所有方法)】
注意:静态成员函数中不可以访问非静态数据成员,只能访问静态数据成员
static修饰的成员属性、成员函数的声明都要放置在public公有访问权限中
static修饰成员函数 示例
CStaff.h
#ifndef CSTAFF_H
#define CSTAFF_H
class Staff
{
public:
Staff();
Staff(int id,char *name,char *pwd,int prole);
~Staff();
static int num;//静态数据成员 放在公有的
static int getNum();//静态成员函数
private:
int ID;
char name[20];
char pwd[20];
int role;
protected:
};
#endif
//只能获取num
int Staff::getNum()
{
return num;
}
main.cpp
#include<iostream>
using namespace std;
#include"CStaff.h"
int main()
{
//静态成员放在public声明
//静态成员所有对象共享,属于类
//静态成员不属于任何一个对象
Staff s1(1001,"lily","123456",1);
cout<<"num = "<<Staff::getNum()<<endl;//num = 1001
return 0;
}
补充:静态成员函数中不可以访问非静态数据成员 下面给出示例
static char * getName(); //static获取不到非静态,只能获取静态
char * Staff::getName()
{
return name;// 静态函数中不能访问非静态成员
//静态函数中没有this指针
}
静态static使用小结:
static修饰成员属性,可以实现数据共享
static修饰成员函数,独立于对象,属于类,直接类名 域运算符 函数名访问即可
四:引用传参
为什么对象不使用按值传递,而使用引用传参:
因为在函数内部需要创建临时变量,走拷贝构造和析构,内存消耗过大,不建议 所以要按引用传参
五:常量const
const修饰主要有以下三种:
1.修饰类对象,对象不能修改,不能访问非const成员方法
2.修饰成员变量,不能被修改,需要初始化列表,示例如下
构造函数: const成员变量名1(值1),const成员变量名2(值2)
3. 修饰成员方法 只能访问数据成员 不能修改 若一定要修改,则使用mutable 修饰想要修改的数据成员
初步了解const
使用const常量 修饰指针变量 可以改变地址 不可以改变值,示例如下
int a=10,b=20;
const int *p =NULL;//const修饰
p = &a;
cout<<*p<<endl;//10
p = &b;
cout<<*p<<endl;//20
// *p = 200; //可以修改地址 不可以改变值
1.const 修饰类对象
不能访问非const成员方法(普通的成员函数/方法)
//报错
const CLabel title(35,7,10,2,"点菜系统");
//const修饰对象 不能访问普通成员函数
title.show();
而 静态static修饰的成员函数,独立于对象,属于类,因此const修饰的类对象 可以访问
//const修饰对象 不能访问普通成员函数
//这里不修饰对象(static修饰成员属性,成员方法,独立于对象) 就可以访问了
const Staff s1(1001,"lily","123456",1);
cout<<"num = "<<Staff::num<<endl;//num = 1001
cout<<"num = "<<s1.getNum()<<endl;//num = 1001
2.const 修饰成员变量
需要初始化列表[在默认和带参构造中],
初始化列表中的值只可以访问,不能够修改
#ifndef CSTAFF_H
#define CSTAFF_H
class Staff
{
public:
Staff();
Staff(int id,char *name,char *pwd,int prole);
~Staff();
static int num;//静态数据成员 放在公有的
static int getNum();
void getId(int num); //成员函数
private:
int ID;
char name[20];
char pwd[20];
int role;
const int k;//const修饰成员变量
protected:
};
#endif
初始化列表[在默认和带参构造中]:
#include"CStaff.h"
#include<iostream>
using namespace std;
int Staff::num = 1000;//静态成员的初始化
Staff::Staff():k(5)//const成员初始化 初始化列表
{
Staff::num++;
}
Staff::Staff(int id,char *name,char *pwd,int prole):k(5)//const成员初始化 初始化列表
{
this->ID = id;
strcpy(this->name,name);
strcpy(this->pwd,pwd);
this->role = prole;
Staff::num++;
}
Staff::~Staff()
{
}
//只能获取num
int Staff::getNum()
{
return num;
}
void Staff::getId(int num)
{
// cout<<this->ID<<endl;//只能访问
// this->ID = num; //不能修改
// k = num; //不可以修改
cout<<k<<endl; //只能访问
}
初始化列表中的值,只能够访问,不能够修改
如下示例,只能访问k的值 ,不能修改k的值
初始化列表中的值,只能访问:
void getId();
void Staff::getId()
{
cout<<k<<endl;
}
初始化列表中的值,不能修改:
void getId(int num);
void Staff::getId(int num)
{
k = num; //不可以修改
}
main.cpp测试:
#include<iostream>
using namespace std;
#include"CStaff.h"
int main()
{
Staff s1(1001,"lily","123456",1);
cout<<"num = "<<Staff::num<<endl; //num = 1001
cout<<"num = "<<s1.getNum()<<endl;//num = 1001
cout<<"k="; //k=5
s1.getId();//只能访问
// s1.getId(10);// const 不能再赋值其他,只能访问(不能修改)
return 0;
}
3.const 修饰成员方法
const修饰成员方法 只能访问数据成员 不能修改数据成员
如果一定要修改 则 使用mutable 修饰 想要修改的数据成员即可
#ifndef CSTAFF_H
#define CSTAFF_H
class Staff
{
public:
Staff();
Staff(int id,char *name,char *pwd,int prole);
~Staff();
static int num; //静态数据成员
// static char * getName(); //static获取不到非静态,只能获取静态
static int getNum(); //静态成员函数
// void getId(int num); //成员函数
void getId(int num) const;//const修饰成员方法(函数)
private:
mutable int ID;//真的想要改变值,使用mutable
char name[20];
char pwd[20];
int role;
const int k;//成员变量
protected:
};
#endif
void Staff::getId(int num) const//const修饰成员方法
{
// cout<<this->ID<<endl;//只能访问数据成员属性
// this->ID = num; //不能修改数据成员属性
// k = num; //初始化列表中的值,不可以修改
cout<<k<<endl;//初始化列表中的值,只能访问
}
若一定要修改就使用mutable,示例如下
mutable int ID;//真的想要改变值,使用mutable
mutable可以修改,但是最好不要使用,因为这样会破坏封装性
常量const使用小结:
const修饰成员属性,成员函数/方法,只能访问数据成员而不能修改数据成员 [对成员函数/方法虽有mutable但不建议使用,要不就不使用const修饰即可]
const修饰对象 不可以访问普通成员(属性)函数[非const成员函数],可以访问静态static修饰的成员变量,静态static修饰的成员函数
六:对象数组 & 对象指针数组
对象数组 示例
CButton btns[3] = {
CButton(25,18,6,3,"登录"),
CButton(45,18,6,3,"退出")
};
for(int i=0;i<2;i++)
{
btns[i].show();
}
return 0;
对象指针数组 示例
程序员手动分配释放内存空间,C++中使用 new/delete
//对象指针数组 访问
CButton *btns[3] = {
new CButton(25,18,6,3,"登录"),
new CButton(45,18,6,3,"退出")
};
for(int i=0;i<2;i++)
{
btns[i]->show();
}
for(i=0;i<2;i++) //指针 手动删除
{
delete btns[i];
}
return 0;