实现梦想的过程从来都不是轻轻松松的,你要打败很多很多的迷茫、委屈、懒惰、软弱、你可能随时都要给自己打气加油,管住那个想退缩的自己。
前言
类和对象的关系,如同建筑设计图纸与建筑物的关系,类是对象的模板,对象是类的实体。
类的定义
类是对象的抽象,是一种自定义数据类型,它用于描述一组对象的共同属性和行为
类的定义格式:
class 类名
{
权限控制符:
成员;
}
● class是定义类的关键字。
● 类名是类的标识符,遵循标识符的命名规则。
● 类名后面是一个大括号,类的所有成员要在这一大括号中声明,类中可以定义成员变量(属性)和成员函数(方法),成员变量用于描述对象的属性,成员函数用于描述对象的行为。
● 声明类的成员时,通常需要使用权限控制符限定成员的访问权限。权限控制符有:public(公有)、protected(保护)和private(私有)。
● 括号后面的“;”表示类的第一结束。
列如:定义一个时间类,该类描述时间的属性:时分秒,该类的行为包括:获取打印时间,获取分钟。具体的代码:
class MyClock
{
public:
// void set_time();//声明一个设置时间的成员函数
void print_time();//声明一个打印时间的成员函数
int get_min();//声明一个获取分钟的成员函数
protected:
int hour,min,secongd;
};
**通常情况下,类的成员函数在类中声明,在类外实现。**在类外实现成员函数,必须在返回值之后、函数名之前加上所属的类作用域,即“类名::”,表示函数属于哪个类。在类外实现成员函数的格式如下所示:
返回值类型 类名::函数名称(参数列表) {
函数体
}
}
void MyClock::print_time()
{
//获取系统时间
time_t val = time(0);
struct tm *ptr = localtime(&val);
hour = ptr->tm_hour;
min = ptr->tm_min;
secongd = ptr->tm_sec;
cout << "时间:"<< hour << ":" << min << ":" << secongd<<endl;
//return s;
}
int MyClock::get_min()
{
cout << min << endl;
return min;
}
如果函数名前没有类名和作用域限定符“::”,则函数不是类的成员函数,而是一个普通的函数。
2.权限控制符介绍
public:公有权限 类外部通过对象直接访问(可以被所属类的成员函数、类对象、派生类对象、友元函数、友元类访问。)
protected:保护权限 只能在类内部或子类内部访问(可以被所属类的成员函数、派生类对象、友元类和友元函数访问。)
private:私有权限 只能在类内部访问 (只能被所属类的成员函数、友元函数、友元类访问。)
默认权限:private
对象的创建与使用
定义了类,就相当于定义了一个数据结构类型,类与int、char等数据类型的使用方法是一样的。类定义的变量称该类的对象。
格式:类名 对象名;
**问题:**类中既可以有成员变量,又可以有成员函数,那么一个类的对象中包含了什么?如何计算 一个类的大小?
创建对象后,系统会为对象分配内存空间,用于存储对象成员。每个对象都有成员变量和成员函数两部分
因此在创建对象时为每一个对象分配独立的内存空间,存储成员变量的值。
C++用同一块空间存储同类对象的成员函数代码,每个对象调用同一段代码
// 类中既有成员变量,又有成员函数
class A1 {
public:
void f1(){}
private:
int _a;
};
// 类中仅有成员函数
class A2 {
public:
void f2() {}};
// 类中什么都没有---空类
class A3{};
int main()
{
printf("%d %d %d", sizeof(A1), sizeof(A2), sizeof(A3));
}
运行结果:sizeof(A1) : 4 sizeof(A2) : 1 sizeof(A3) : 1
结论:
一个类的大小,实际就是该类中”成员变量”之和,当然要注意内存对齐
注意空类的大小,空类比较特殊,编译器给了空类一个字节来唯一标识这个类的对象。
存储数据的目的是访问数据,即访问对象的成员。对象的成员变量和成员函数的访问可以通过“.”运算符实现。即:
对象名.成员变量
对象名:成员函数
具体实例:
#include <iostream>
using namespace std;
class MyClock
{
public:
// void set_time();//声明一个设置时间的成员函数
void print_time();//声明一个打印时间的成员函数
int get_min();//声明一个获取分钟的成员函数
protected:
int hour,min,secongd;
};
/*
void MyClock::set_time()
{
cin >> hour >>min >> secongd;
}
*/
void MyClock::print_time()
{
//获取系统时间
time_t val = time(0);
struct tm *ptr = localtime(&val);
hour = ptr->tm_hour;
min = ptr->tm_min;
secongd = ptr->tm_sec;
cout << "时间:"<< hour << ":" << min << ":" << secongd<<endl;
//return s;
}
int MyClock::get_min()
{
cout << min << endl;
return min;
}
int main()
{
MyClock myclock;//创建myclock对象
//myclock.set_time();
myclock.print_time();//调用对象的成员函数
myclock.get_min();//调用对象的成员函数
return 0;
}
new创建类对象
例如:
int main()
{
MyClock *pr = new MyClock;
pr->print_time();
pr->get_min();
return 0;
}
封装
在类的封装设计中通过权限控制方式实现类成员的访问,目的是隐藏对象的内部实现细节,只对外提供访问的接口。
在定义类时,将类中的成员变量设置为私有或保护属性,即使用private或protected关键字修饰成员变量。使用类提供的公有成员函数(public修饰的成员函数),如用于获取成员变量值的getXxx()函数和用于设置成员变量值的setXxx()函数,操作成员变量的值。
class Demo
{
public:
void setval(int val)
{
this->myval = val;
}
int getval()
{
return myval;
}
private:
int myval;
}
其中myval私有成员变量,可以通过setval()函数访问,相当于对外的接口。因为private只能在类的内部进行访问。
this指针
this指针是C++实现封装的一种机制,它将对象和对象调用的非静态成员函数联系在一起,从外部看来,每个对象都拥有自己的成员函数。当创建一个对象时,编译器会初始化一个this指针,指向创建的对象,this指针并不存储在对象内部,而是作为所有非静态成员函数的参数。
实现类的成员函数时,如果形参与类的属性重名,可以用this指针解决
void Student::setName(string name)
{
this->name = name;
}
string Student::getName()
{
return this->_name;
}
如果类的成员函数返回值为一个对象,则可以使用return*this返回对象本身。
例如:当创建对象stu时,编译器会初始化一个this指针指向对象stu,通过stu调用成员函数setNam e()与getNam e()时,编译器会将this指针作为两个函数的参数。