C++启蒙笔记(六)---类基础、构造函数

一、初识

1.1 基本概念

  • 类定义:面向对象程序设计核心,封装一类数据和方法的蓝图,以实类来初始化及调用
  • 类构成:类变量,类方法,且其作用域调用受访问修饰符限制
  • 类变量:不同对象会开辟不同的存储空间来存放类变量
  • 类方法
    • 声明及定义:类内声明,可在类内或类外定义
    • 写法:常规在类内声明(放在头文件*.h中),在类外定义(实现文件*.cpp中)
    • 本质:同一类的所有对象共用同一组类方法,即每种方法只有一个副本

  • 访问修饰符
    • private:默认,只有定义的类可以访问,派生类和类外都不可直接访问
    • public:开放访问,定义类方法位置,即类接口定义位置,外部需要点运算符调用
    • protected:定义的类和派生类可以访问,外部不可直接访问

  • 重载:类中,方法名相同,参数不同,返回类型无限制。 每个重载方法都必须有唯一的参数类型列表

1.2 类基础写法

  • 功能意图:类为长方体,通过类函数设置长方体长宽,进而求长方体底面积

  • 基础代码写法1

    #include <iostream>
    
    using namespace std;
    
    class Box
    {
    // private私有成员访问修饰符:
    //  通常是用来封装类的数据,私有函数,只有定义的类可访问
    private:
        double _length;
        double _width;
        string _name;
    
    // public公有成员访问修饰符:
    //  通常是用来定义类的函数,进而对外界提供调用类相应功能的接口
    public:
        // 类的构造函数:函数名同类名,通常用于初始化类的数据,
        //            函数体可为空,不可有return语句
        Box()
        {
            // 类内调用私有变量,写法如下
            _length = 5.0;
            _width = 10.0;
            _name = "无名"
        };
        
        // 析构函数:用来显式释放类的存储空间和资源,
        // 		   函数体可为空,栈内存选填,堆内存必须
        ~Box() { cout << "这是"<< _name << "的析构函数被调用" << endl; };
        
        // 类函数实现一:类外定义,类内声明
        void set(const string &name, double length, double width);
        
        // 类函数实现二:类内定义,类内声明
        void area(void)
        { // 类内调用私有变量
        	cout << _name << "的area函数被调用" << endl;
            double area = _length * _width;
            cout << "长:" << _length << ",宽:" << _width << endl;
            cout << "面积为:" << area << endl;
        };
    };
    
    // 类外定义类的函数,注意返回值void,类前缀Box::
    void Box::set(const string &name, double length, double width)
    { 	// 类外定义类的函数体调用类的私有变量
    	_name = name;
        _length = length;
        _width = width;
        cout << _name << "的set函数被调用" << endl;
    }
    
    int main()
    {
        // 声明定义类:此处调用类的构造函数
        Box box1, box2;
        // box1调用类的set函数
        string name = "box1";
    	box1.set(name, 20.0, 30.0);
        box1.area();
        // box2使用的是类的构造函数赋的值
        box2.area();
        // 析构函数:此处调用类的析构函数
    }
    
  • 返回值显示

    box1的set函数被调用
    box1的area函数被调用
    长:20,宽:30
    面积为:600
    无名的area函数被调用
    长:5,宽:10
    面积为:50
    这是无名的析构函数被调用
    这是box1的析构函数被调用
    
  • 写法2(仅字符串变量不同,返回值同上)

    #include <iostream>
    // 用C风格字符串变量
    #include <cstring>
    
    using namespace std;
    
    class Box
    {
    private:
        double _length;
        double _width;
        char _name[10];
    
    public:
        Box()
        {
            _length = 5.0;
            _width = 10.0;
            // 字符串赋值
            strcpy(_name, "无名");
        };
    
        ~Box() { cout << "这是" << _name << "的析构函数被调用" << endl; };
    
        void set(const char *name, double length, double width);
    
        void area(void)
        {
            cout << _name << "的area函数被调用" << endl;
            double area = _length * _width;
            cout << "长:" << _length << ",宽:" << _width << endl;
            cout << "面积为:" << area << endl;
        };
    };
    
    void Box::set(const char *name, double length, double width)
    { // 字符串变量深拷贝
        strcpy(_name, name);
        _length = length;
        _width = width;
        cout << _name << "的set函数被调用" << endl;
    }
    
    int main()
    {
        Box box1, box2;
        box1.set("box1", 20.0, 30.0);
        box1.area();
        box2.area();
    }
    

1.3 类的内联函数

  • 写法(内联函数堆内存中创建对象const修饰this
    class Box
    {
    private:
        ...
    
    public:
    	...
    	// const:此函数不修改调用对象,编译时检测
    	// 		修饰隐含传入的this,见下节
        void area() const;
    };
    
    // 内联函数定义:一般只有一个语句的函数用此方法
    inline void Box::area() const
    {
        cout << "面积是:"_length * _width << endl;
    }
    // 以下了解下即可,进阶详解
    int main()
    {
    	// 这是堆内存中创建类对象,指针box1是在栈内存中
        Box *box1 = new Box(1, 1);
    	// 指针调用类方法写法
        box1->area();
    }
    

1.4 this指针

  • 定义:
    • 本质:每一个对象都能通过 this 指针来访问自己地址
    • 特性:this 指针是所有成员函数隐含参数
    • 简记:谁调用函数,this就指向谁
  • 代码示例
    #include <iostream>
    
    using namespace std;
    
    class Box
    {
    private:
        double _length;
    
    public:
        Box(double length = 0)
        {
            _length = length;
        };
    
        void print() const
        {
            // _length:是this->_length的简写
            cout << _length;
        };
    
        void transprint() const
        {
            // a、this可以调用本对象任意函数,
            // b、针对的是对象自己的数据
            // c、this是函数隐式传递的
            this->print();
        };
    };
    
    int main()
    {
        Box box1(2.0);
        box1.transprint();
        // 屏幕输出2
    }
    

二、构造函数

2.1 三种构造函数写法

  • 代码示例(三种构造函数C风格字符串深拷贝
    #include <iostream>
    #include <cstring>
    
    using namespace std;
    //------------------类声明------------------//
    class Box
    {
    private:
        double _length;
        char _name[10];
    
    public:
        // 类构造函数重载:注意无返回值
        // a、不传参默认构造函数
        Box();
        // b、带参数的默认构造函数:有默认值的在类声明里写,类外定义不写
        Box(const char *name, double length= 2.1);
        // c、复制构造函数:函数虚实参传递也会用到这个
        Box(const Box &obj);
    
        void show();
    
        ~Box(){};
    };
    
    //------------------类函数定义------------------//
    // a、若无构造函数:程序会自动创建一个Box::Box(){}
    Box::Box(void)
    {
        // strcpy函数要求第二个参数类型是const char *__src
        strcpy(_name, "无名");
        _length = 1.0;
        cout << "调用无参构造函数" << endl;
    }
    
    // b、函数可含默认参数,const char *__src为strcpy函数要求
    Box::Box(const char *name, double length)
    {
        strcpy(_name, name);
        _length = length;
        cout << "调用传参构造函数" << endl;
    }
    
    // c、复制构造函数:用已初始化过的类对象初始化类对象
    Box::Box(const Box &obj)
    {
        strcpy(_name, obj._name);
        _length = obj._length;
        cout << "调用复制构造函数" << endl;
    }
    
    void Box::show()
    {
        cout << _name << ":" << _length << endl;
    }
    
    //------------------主函数------------------//
    int main()
    {
        // a、调用不传参默认构造函数,不可用Box box1();调用
        Box box1;
        // b、调用传参默认构造函数
        Box box2("box2", 2.0);
        // b、调用传参默认构造函数,使用函数默认参数
        Box box3("box3");
        // c、调用复制构造函数
        Box box4(box2);
    
        box1.show();
        box2.show();
        box3.show();
        box4.show();
    }
    
  • 程序显示
    调用无参构造函数
    调用传参构造函数
    调用传参构造函数
    调用复制构造函数
    无名:1
    box2:2
    box3:2.1
    box2:2
    

2.2 类对象数组

  • 功能:批量初始化类对象
  • 代码示例
    // 类相关见2.1
    //------------------主函数------------------//
    int main()
    {
        Box box[3] = {Box("box0", 0), Box(box[0])};
        box[0].show();
        box[1].show();
        box[2].show();
    }
    

    Box box[3];:会三次调用无参构造函数

  • 显示
    调用传参构造函数
    调用复制构造函数
    调用无参构造函数
    box0:0
    box0:0
    无名:1
    

上一篇:C++启蒙笔记(五)—函数进阶
下一篇:C++启蒙笔记(七)—类运算符重载

  • 3
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值