c++学习笔记之封装篇(上)

一、类对象

假设我们由Tv这个类,定义如下

注意class结尾要加上分号

class Tv()
{
    int width;
    int height;
    int volume;
    void changeVolume()
    {
        //changeVolume
    }
};

类的实例化有两种方法,一种是栈中实例化。另一种则是堆中实例化

而这两种方法除了在用法上有区别以外(区别见下面代码),内存管理也有区别(栈不用考虑内存回收问题,系统会自动回收,而堆则需要程序员主动释放内存)。

1.实例化

  • 从栈中实例化对象
Tv tv;

或者 

Tv tv[20]  //实例化对象数组     从栈中实例化系统自动回收内存
  • 从堆中实例化对象

实例化一个对象后还需要判断是否成功申请到内存

Tv *p = new Tv();    
Tv *q = new Tv[20];  //开辟一块对象内存  

if(p==NULL)
{
    cout<<"类实例化失败"<<endl;
}

//从堆中实例化数组对象,需要程序员回收
delete p;   
delete[]q; 
p = NULL;
q =NULL;

访问数据

  • 通过栈实例化的对象访问数据成员:
tv.volume = 5;   
tv.changeVolume();
  • 通过堆实例化的对象访问数据成员:
tv->volume = 5; 
tv->changeVolume();

二、string

可以很方便的定义一个字符串,而不再是使用麻烦的char[]. 使用方法:

// 引入string头文件
#include <string>

初始化方法

注意:第4个初始化方法中的第二个参数只能是一个字符,不能是字符串。

常用操作

对于字符串相加操作,需要注意一点,不能直接使用两个字符串相加,中间必须得有字符串变量连接才行(下面例子中最后一个赋值语句是错误的),具体例子如下:

另外如果要将字符串和整数连在一起输出,则需要在整数前加上 << 进行处理,直接用 “+” 是无效的。

string name;
cin>>name;
cout<<name<<name.size()<<endl;

三、构造函数

  • 构造函数必须与类同名,起到的作用与python中的 **_ init > _()** 函数类似,即对类进行数据初始化。
  • 构造函数在对象实例化时被自动调用,且只调用一次。
  • 构造函数没有返回值,不需要return值。
  • 构造函数可以重载。

1. 构造函数分为有参与无参

举个栗子:

class Student
{
    // 无参构造函数
    Student()
    {
        m_iHeight = 180;
        m_iWeight = 70;
    }
    
    // 有参构造函数
    Student(int weight, int height)
    {   
        m_iWeight = weight;
        m_iHeight = height;
    }
    
    private:
        int m_iWeight;
        int m_iHeight;
}

2. 构造函数初始化列表

在初始化对象时,初始化列表是最先执行的,所以有的时候对于const变量我们也可以提前赋值。

语法: 类名():变量1(参数),变量2(参数){}

用法: 我们都知道一个人的身份证信息一般来说是不能随意篡改的,所以我们会使用const 来修饰,但是因为const修饰后,变量则不能再赋值,但是因为每个人的身份证又不一样,我们不可能在使用const修饰的同时进行赋值,那怎么办呢?所以这里用到了初始化列表来达到这么一个效果,详见下面的代码示例:

class Student
{
    // 正确示例
    // 初始化列表
    Student(string id):m_iId(id)
    {
        // 初始化成功
    }
    
    // 编译会报错
    // Student(string id)
    // {
    //    m_iId = id;
    // }
    
    private:
      const string m_iId;
}

初始化类数组

Coordinate *coorArr = new Coordinate[2]{{1,2},{3,4}};

具体示例

#include <iostream>
using namespace std;
class Coordinate
{
    
    public:
        Coordinate(int x,int y):m_iX(x),m_iY(y)
        {
            cout<<m_iX<<","<<m_iY<<endl;
        }
        // 打印坐标的函数
        void printInfo()  
        {
            cout<<m_iX<<","<<m_iY<<endl;
        }
    private:
        int m_iX;
        int m_iY;
};
int main(void)
{
    //定义对象数组
    Coordinate *coorArr = new Coordinate[2]{{1,2},{3,4}};
    
    
    //遍历数组,打印对象信息
    for(int i = 0; i < 2; i++)
    {
        coorArr[i].printInfo();
    }   
    return 0;
}

3. 拷贝构造函数

  • 不能重载 格式: 类名(const 类名& 变量名)

关于拷贝构造函数更具体的解析参考: C++拷贝构造函数详解

4.析构函数

与构造函数相反,当一个对象的生命周期结束时,C++会自动调用一个特殊的成员函数,即析构函数进行善后工作,对成员变量所占内存进行释放操作。 格式:(不需要参数) ~类名(){}

class Student
{
    // 构造函数,初始化列表
    Student():m_iId(110){};
    // 析构函数,c++可以自动生成
    ~Student(){};
}

对象的生命历程: 申请内存-->初始化列表-->构造函数-->参与运算-->析构函数-->释放内存

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏Java帮帮-微信公众号-技术文章全总结

第二十天 IO-异常file类【悟空教程】

在Java等面向对象的编程语言中,异常本身是一个类,产生异常就是创建异常对象并抛出了一个异常对象。Java处理异常的方式是中断处理。

14050
来自专栏工科狗和生物喵

【计算机本科补全计划】Java学习笔记(六) 循环+分支结构

正文之前 这两节太弱了。基本大一的C++程序设计课就足够对付理解了。所以还是水一波吧,实在没办法,整个教程还是全部抄全吧。免得到时候新人小白入门的时候还要去看别...

36490
来自专栏大闲人柴毛毛

剑指offer——面试题9计算斐波纳切第n个数

/** * 计算斐波纳切数列的第n个值 * @author chibozhou * */ public class Fibonacci { /** ...

38670
来自专栏猿人谷

C++ 模板学习

1. 模板的概念。 我们已经学过重载(Overloading),对重载函数而言,C++的检查机制能通过函数参数的不同及所属类的不同。正确的调用重载函数。例如,为...

257100
来自专栏Vamei实验室

Python进阶04 函数的参数对应

我们已经接触过函数(function)的参数(arguments)传递。当时我们根据位置,传递对应的参数。我们将接触更多的参数传递方式。 回忆一下位置传递: d...

20570
来自专栏好好学java的技术栈

“面试不败计划”: java语言基础面试题(三)

13030
来自专栏前端桃园

[第 3 期]JavaScript数据结构之数组栈队列

15250
来自专栏林冠宏的技术文章

由 System.arraycopy 引发的巩固:对象引用 与 对象 的区别

首先明确一点,System.arraycopy 操作的是数组,效果是深复制。 是不是觉得怎么和你印象的中不一样? 重点来了,对于对象数组,例如: User[]...

13840
来自专栏我的技术专栏

C++ 异常机制分析

18840
来自专栏CodeSheep的技术分享

Java编程思想学习录(连载之:内部类)

221110

扫码关注云+社区

领取腾讯云代金券