• c++ 对象和类


    1 使用构造函数

    // 显式的使用构造函数
    Stock food = Stock("world",150,1.25);
    // 隐式的使用构造函数
    Stock food("world",150,1.25);
    
    • 1
    • 2
    • 3
    • 4

    2、默认构造函数

    默认构造函数是指没有提供显示初始值时,用来创建对象的构造函数。

    // 如果没有提供任何构造函数,C++ 将自动提供默认构造函数。不做任何工作
    Stock food;
    
    • 1
    • 2

    注意事项:
    当且仅当没有提供任何构造函数时,编译器才会提供默认构造函数。当类定义了构造函数(如Stock(const char* co,int n,double ptr)),但是没有提供默认构造函数如Stock(){},则下面的声明将出错:
    Stock stock1;
    定义默认构造函数的方式有两种:
    1、一种给已有构造函数的所有参数提供默认值:

    Stock(const sting & co = "world",int n = 0,double pr = 0.0);
    
    • 1

    2、另一种通过函数重载来定义另外一个构造函数,一个没有参数的构造函数:

    Stock();
    
    • 1

    由于只能有一个默认构造函数,因此不能同时采用这两种方式。
    实际工作中,应该初始化所有的对象,确保所有的成语开始就有已知的合理数值。如下:

    Stock::Stock(){
      	company = "no name";
     	shares = 0;
      	share_val = 0.0;
      	total_val = 0.0;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    设计类时,应该提供对所有类成员做隐式初始化的默认构造函数。
    隐式的调用默认构造函数时候,不需要使用圆括号如:

    Stock food;
    
    • 1

    析构函数

    析构函数:完成清理工作。如果构造函数使用new 来分配内存,则析构函数使用delete 来释放这些内存。构造函数没有使用new 来分配内存,则析构函数实际上没有需要完成的任务。这种情况下只需要让编译器生成一个什么都不需要做的隐式析构函数即可。
    声明和定义方法:

    ~Stock();
    Stock::~Stock(){}
    
    • 1
    • 2

    实际工作中,不应该在代码中显示地调用析构函数,什么时候调用析构函数由编译器决定。

    this 指针

    类可能涉及到两个对象,因此这种情况下需要使用this指针。this 指针指向用来调用成员函数的对象。

    /* 该函数隐式的访问一个对象,而显示的访问另一个对象,并返回其中一个
    对象的引用。
    */
    
    const Stock & topval(const Stock & s) const;
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    对象数组

    /*
    使用不同的构造函数,初始化不同的数组元素,由于只是初始化了数组的部分元素,余下的元素将使用默认构造函数进行初始化。
    */
    const int STKS = 10;
    Stock stocks[STKS] = {
      Stock("NanoSmart",12.5,20),
      Stock(),
      Stock("food",130,3.25),
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

    作用域为类的常量

    符号常量的作用域为类很有用。
    创建一个由所有对象共享的常量

    class Bakery
    {
      private:
        const int Months = 12; 
        double costs[Months];//非法。
    }
    /*
    声明类只是描述了对象的形式,并没有创建对象。因此,在创建对象之前,并没有
    用于存储值的空间。
    编译器报错 invalid use of non-static data member 'Bakery::Months '
    */
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11

    正确的方法:
    第一种:
    在类中声明一个枚举。在类中声明的枚举的作用域为整个类。因此用枚举为整型常量提供作用域为整个类的符号名称。

    class Bakery
    {
      private:
        enum{Months = 12}; 
        double costs[Months];//合法。
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    第二种:
    使用关键字static。该常量将与其他静态变量存储在一起,而不是存储在对象中。

    class Bakery
    {
      private:
        const static int Months = 12;// 创建的是常量,合法,该常量将与其他静态变量存储在一起。
        // 静态成员初始化的特例:静态成员是整型或者枚举型const ,可以在类声明中进行初始化
        double costs[Months];//合法。
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    静态成员

    静态变量不能在类的声明中进行初始化。因为类声明描述了如何分配内存,但是并不分配内存。否则编译器将报错。对于静态的类成员,可以在类声明之外,使用单独的语句来进行初始化。因为静态类成员是单独存储的,而不是对象的组成部分。

    //strngbad.h 文件
    class StringBad
    {
      private:
       static int num_strings;
    }
    # strngbad.cpp 文件
    //初始化静态成员,初始化使用了作用域运算符,但没有使用关键子static
    int StringBad::num_strings = 0;
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
  • 相关阅读:
    请你设计一个可以解释字符串 command 的 Goal 解析器
    LeetCode Cookbook 数组习题(8)
    【小程序源码】视频壁纸支持多种分类短视频另外也有静态壁纸
    【若依(ruoyi)】ztree初始化
    Unity URP简单烘焙场景步骤
    codeforces:C. Almost All Multiples【构造 + 贪心】
    SpringBoot整合SQLite
    【融合ChatGPT等AI模型】Python-GEE遥感云大数据分析、管理与可视化及多领域应用
    并发修改异常
    Linux :mysql数据库自动备份
  • 原文地址:https://blog.csdn.net/weixin_39674445/article/details/128051868