“类和对象“

一.类和对象的定义

1.struct 类名{数据和数据相关的函数};(类外可访问)

struct定义的类,默认访问权限为public

2.class 类名{所有的成员};(类外不可访问)

class定义的类,默认访问权限为private

class Student{
  void SetStudentInfo(const char* name, const char* gender, int age){
    strcpy(_name, name);
    strcpy(_gender, gender);
    _age = age;
  }
  void PrintStudentInfo(){
    cout << _name << " " << _gender << " " << _age << endl;
  }

 char _name[20];
 char _gender[3];
 int _age;
};

int main(){
  Student Stu;
  stu.SetStudentInfo("abc", "nan", 30);
  stu.PrintStudentInfo();
  cout << stu._gender <<endl;
}

可以声明在.h里面,定义在.cpp里面

//.h文件-----保存在person.h中
class Person{
 public:
  void showInfo();
}

//.cpp文件-----保存在person.cpp中
//函数在类外定义,需要加类的作用域
#include "person.h"
void person::showInfo(){
  cout << _name << "-" << _sex << "-" << _age << endl;
}

函数在类外定义,需要加类的作用域

void person::showInfo(){
  cout << _name << "-" << _sex << "-" << _age << endl;
}

①访问类成员

  • 通过"."的形式
  • 如果是真真,通过"->"的形式

//this函数用于区分所要输入的数据,相当于隐式的函数形参(this指针在不做解引用的情况下可以为空)

class Date{
void Display(){
  cout << _year << "-" << _month << "-" << _day << endl;
  A a;
}

void SetData(int year, int month, int day){
  this -> _year = year;
  _month = month;
  _day = day;
}

int _year;
int _month;
int _day;
};

int main(){
  Date d1, d2;
  d1.SetData(2018, 5, 1);
  d2.SetData(2018, 5, 2);
}

3.类的大小 == 类实例化后对象的大小

按照结构体的规则计算

  • 成员函数不占对象的空间
  • 不含成员变量
  • 空类/不含成员变量的类为1字节

4.类的实例化(定义一个类的过程)

类中有6个默认成员函数:
在这里插入图片描述

①构造函数(可以重载)-----初始化一个对象内容的函数,不是创建对象(编译器在创建对象时,自动调用构造函数)

//默认构造:无参构造、全缺省构造
//如果不写构造函数,编译器自动生成一个无参的构造函数

//调用无参函数

Data d;

//不能显示调用构造函数

d.Data(2020, 1, 2);  //报错

//不能有多个默认构造函数
//默认构造函数可以为全缺省函数
//无参/带参的构造函数中隐含了this指针,在函数中调用过程中可以用this指针访问里面的数据,也可以不用

初始化列表-----:

以下三种情况必须在定义的时候初始化(即使用初始化列表)

  • const int _n; //const修饰的变量
  • int& _ref; //引用类型
  • Time _t; //没有默认构造函数(不用参数调用)的类
Date(int year, int month, int day){
  :_year(year)
  ,_month(month)
  ,_day(day)
}
初始化列表的运行顺序

由变量声明的顺序决定其运行顺序

class A
{
public:
 A(int a)  //初始化(定义)
 :_a1(a)
 ,_a2(_a1)
 {}
 
 void Print() {
 cout<<_a1<<" "<<_a2<<endl;
 }
 
private:
 int _a2;   //声明
 int _a1;
}
int main() {
 A aa(1);
 aa.Print();
}

因为是先声明_a2,再声明_a1,所以,初始化时,_a2需要使用_a1来使用,_a1此时还没有初始化,_a1为随机值,所以_a2也为随机值

正常的初始化列表 VS 匿名
int main(){
A aa1(1);   //他的生命周期在main函数域
A(2);      //匿名对象,他的生命周期在这一行
}
int main(){
A aa1(1);   //他的生命周期在main函数域
A(2);      //匿名对象,他的生命周期在这一行
Solution s;
cout << s.StrToInt("1234") << endl; // 
//这个调用对象其他地方都不用,就这一行用,那么就可以用匿名对象
cout << Solution().StrToInt("1234") << endl; //这两行一样的效果
return 0;
}
初始化列表 VS 正常的初始化
  • 初始化列表是在定义时直接进行初始化,而正常的初始化是先给对象随机值,再进行初始化的过程
构造函数的多种使用方式

A aa1(1);
A aa2 = 2; //隐式类型转换,结果调用析构函数
//先构造一个A(2)匿名临时对象,再用这个临时对象去拷贝构造aa2
//编译器将这个过程优化了,直接调了构造函数,不构造A(2)临时对象了

匿名临时对象的应用
class Solution{
 public:
    int n = str.Size();
    if(n < 1)
     return 0;
    int flag = 1;
    int ret = 0;
}

int main(){
//1
  string str(1234);
  cout << Solution().StrToInt(str) << endl;
//2
  cout << Solution().StrToInt(string("1234")) << endl;
//3
  cout << Solution().StrToInt("1234") << endl; 
}
explicit-----不允许隐式类型转换发生
explicit A(int a)
   :_a(a)
   {}

②析构函数(没有参数,没有返回值,不能重载)-----完成类的资源清理

  • 函数生命周期结束时,自动调用析构函数
    //对象销毁的时候,编译器自动调用析构,销毁资源(在栈空间上的数据)
    //不显示定义析构,编译器会自动生成默认的析构函数
    函数名:在类名前加~
~SeqList(){
  if(_pData){
    free(_pData);     //释放堆上的空间
    _pData = NULL;    //将指针置为空
    _capacity = 0;
    _size = 0;
  }
}

③拷贝构造

调用拷贝构造

Date date(2021, 2, 2);
Date copy(date);
Date(int year = 1, int month = 1, int day = 1){
  _year = year;
  _month = month;
  _day =  day;
}

//拷贝构造(编译器自己默认带的是浅拷贝-----只复制对象,不一定复制内容)
//若没有显示定义,会自动生成
Date(const Date& d){              
   _year = d._year;
  _month = d._month;
  _day =  d._day;
}

int main(){
  Date date(2021, 2, 2);
  Date copy(date);
}

5.类的对象:实例化的变量

二.类中的访问权限

1.public(公有的)-----在类外可访问

2.protected(保护的)-----

3.private(私有的)-----在类外不可访问

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值