C++:类与对象,定义类和构造函数

ops/2025/2/21 6:24:22/

#define _CRT_SECURE_NO_WARNINGS 1
#include <iostream>
using namespace std;

//如何让定义一个类
// 封装
// 1、将数据和方法定义到一起。
// 2、把想给你看的数据给你看,不想给你看的封装起来。  通过访问限定符来实现
class Stack
{
public:
    //1.成员函数
    void Push(int x);
    //void Push(int x)
    //{
    //    //...函数体 
    //}//这种是在类里面定义
    void Pop();//这里是类的申明,类外面定义
    bool Empty();
    //....
private:
    //2.成员变量
    int _a;
    int _size;
    int _capacity;//这里是声明
};

//在类外面定义成员函数
void Stack::Push(int x)
{
    //...
}

// 1、C语言中,struct是用来定义结构体的
// 2、C++中,兼容C的struct定义结构体的用法。但是同时struct也可以用来定义类
// 3、C++中使用class和struct定义类的区别? -》默认的访问限定符

//C
struct ListNode_C
{
    int* _val;
    struct ListNode_C* _next;
    struct ListNode_C* _prev;
};

//C++
struct ListNode_CPP//默认共有
//class ListNode_CPP//默认私有
{
    int* _val;
    //ListNode_CPP* _next;//这个地方不需要加struct
    struct ListNode_CPP* _next;//这个地方也可以这样用,C++兼容C

    ListNode_CPP* _prev;//这是C++当成类的用法

    //还可以定义成员函数
    ListNode_CPP* Create(int val);
};

// 1、声明和定义的区别? 声明是一种承诺,承诺要干嘛,但是还没做,定义就是把这个事落地了

//类中既有成员变量,又有成员函数
class A1
{
public:
    void f1()
    {
    }
private:
    int _a;
    char _ch;
};

//类中仅有成员函数
class A2
{
public:
    void f2()
    {
    }

};

//类中既没有成员函数,也没有成员变量
class A3
{

};
int main()
{
    //类实例化出对象,相当于定义出了类的成员变量
    Stack s1;
    Stack s2;
    Stack s3;

    //s1._a = nullptr;//私有的,不能访问
    s1.Push(1);

    //对象中只存储成员变量,不存储成员函数?为什么?
    cout << sizeof(s1) << endl;
    // 因为一个类实例化出N个对象,每个对象的成员变量都可以存储不同的值,但是调用的函数确是同一个
    // 如果每个对象都放成员函数,而这些成员函数却是一样的,会浪费空间


    // 如何计算一个类实例化出的对象的大小,计算成员变量之和,并且考虑内存对齐规则
    // 没有成员变量的类的大小是1,面试题:为什么是1,而不是0。开1个字节不是为了存数据,而是占位
    cout << sizeof(A1) << endl;
    cout << sizeof(A2) << endl;
    cout << sizeof(A3) << endl;

    return 0;
}


实例化 -》就是用自己定义的类型定义出对象
 1、内置类型,基本类型 int/char/double
 2、自定义类型,class/struct

class Date
{
    // this是谁调用这个成员函数,this就指向谁
public:
    void Init(int year, int month, int day)//void Init(Date* this, int year, int month, int day)
    {
        _year = year;
        _month = month;
        _day = day;
    }

    void Print()//void Print(Date* this)
    {
        cout << _year << "-" << _month << "-" << _day << endl;
    }
private:
    int _year;
    int _month;
    int _day;
};

int main()
{
    Date d1;
    d1.Init(2025, 2, 20); //(&d1,2025,2,20);
    d1.Print();           //(&d1);
    return 0;
}


this指针存在哪里? (也就是存在进程地址空间的哪个区域?)
答:栈上的,因为它是一个形参。(ps:vs下是在ecx这个寄存器,来传递)

 1、下面程序能编译通过吗?
 2、下面程序会崩溃吗?在哪里崩溃?
class A
{
public:
    void PrintA()
    {
        cout << _a << endl;
        //cout << this->_a << endl;//会对空指针this进行解引用,会导致程序崩溃
    }

    void Show()
    {
        cout << "Show()" << endl;
    }
private:
    int _a;
};
int main()
{
    A* p = nullptr; //因为p->PrintA();用的是指针,所以p->Print(p)传的也是指针p
    p->PrintA();  //崩溃
    p->Show();    //正常运行
    //成员函数存在公共的代码段,所有p->Show()这里不会去p指向的对象上找
    //访问成员函数,才会去找

    A a;
    a.PrintA();//p->Print(&a);这个地方a是对象,所以传的是&a,反正传的都是对象的地址
    return 0;
}


构造函数是特殊的成员函数,需要注意的是,构造函数虽然名称叫构造,但是构造函数的主要任
务并不是开空间创建对象,而是初始化对象。
1. 函数名与类名相同。
2. 无返回值。
3. 对象实例化时编译器自动调用对应的构造函数。
4. 构造函数可以重载。

class Date
{
public:
    //构造函数-》在对象构造时调用的函数,这个函数完成初始化工作
    Date(int year, int month, int day)//构造函数没有返回值
    {
        _year = year;
        _month = month;
        _day = day;
    }

    Date()//函数重载
    {
        _year = 0;
        _month = 1;
        _day = 1;
    }

    void Print()
    {
        cout << _year << "-" << _month << "-" << _day << endl;
    }
private:
    int _year;
    int _month;
    int _day;
};
int main()
{
    //对象实例化时自动调用
    Date d1(2025, 2, 20);
    d1.Print();

    Date d2;//Date d2();不能加括号,调无参的不需要加括号,否则编译器不认识
    d2.Print();
    return 0;
}

5. 如果类中没有显式定义构造函数,则C++编译器会自动生成一个无参的默认构造函数,一旦
用户显式定义编译器将不再生成。
class Time
{
public:
    Time()
    {
        cout << "Time()" << endl;
        _hour = 0;
        _minute = 0;
        _second = 0;
    }
private:
    int _hour;
    int _minute;
    int _second;
};

class Date
{
public:
    // 如果用户显式定义了构造函数,编译器将不再生成
    // 我们没有显式定义的构造函数,这里编译器生成无参默认的构造函数(语法双标)
    // 1、针对内置类型的成员变量没有做处理
    // 2、针对自定义类型的成员变量,调用它的构造函数初始化
    void Print()
    {
        cout << _year << "-" << _month << "-" << _day << endl;
    }
private:
  基本类型(内置类型)
    int _year;
    int _month;
    int _day;
  自定义类型
    Time _t;
};

int main()
{
    Date d1;//调用编译器生成的构造函数
    d1.Print();
    return 0;
}


7. 无参的构造函数和全缺省的构造函数都称为默认构造函数,并且默认构造函数只能有一个。
注意:无参构造函数、全缺省构造函数、我们没写编译器默认生成的构造函数,都可以认为是默认构造函数。
class Date
{
public:
    //更好的方式:全缺省
    Date(int year = 0, int month = 1, int day = 1)
    {
        _year = year;
        _month = month;
        _day = day;
    }

    //不能和全缺省同时出现,因为调用的时候会出现歧义,Date d1;
    //Date()//函数重载
    //{
    //    _year = 0;
    //    _month = 1;
    //    _day = 1;
    //}

    void Print()
    {
        cout << _year << "-" << _month << "-" << _day << endl;
    }
private:
    int _year;
    int _month;
    int _day;
};

int main()
{
    Date d1;//调用默认构造函数 -》1、自己实现无参的构造函数  2、自己实现的全缺省构造函数 
                              //3、编译器自动实现的构造函数 Date d1;的特点是不用传参数 
    d1.Print();
    Date d1(2025, 3, 20);
    d1.Print();
    return 0;
}


class Date
{
public:
    更好的方式:全缺省
    Date(int year = 0, int month = 1, int day = 1)
    {
        _year = year;
        _month = month;
        _day = day;
    }

    不能和全缺省同时出现,因为调用的时候会出现歧义,Date d1;
    Date()//函数重载
    {
        _year = 0;
        _month = 1;
        _day = 1;
    }

    void Print()
    {
        cout << _year << "-" << _month << "-" << _day << endl;
    }
private:
    int _year;
    int _month;
    int _day;
};

int main()
{
    Date d1;
    Date d2;
    return 0;
}


http://www.ppmy.cn/ops/160171.html

相关文章

线性代数中的向量与向量空间

线性代数中的向量与向量空间 线性代数是数学的一个分支&#xff0c;它广泛应用于计算机科学、物理学、工程学等领域。在这些领域中&#xff0c;向量和向量空间是构建复杂系统和模型的基础。本文将深入探讨这两个核心概念。 1. 向量&#xff1a;不仅仅是箭头 在线性代数中&am…

C++蓝桥杯基础篇(四)

片头 嗨~小伙伴们&#xff0c;大家好&#xff01;今天我们来学习C蓝桥杯基础篇&#xff08;四&#xff09;&#xff0c;继续练习相关习题。准备好了吗&#xff1f;咱们开始咯~ 题目1 连续整数相加 思路分析&#xff1a; 这道题&#xff0c;我们可以把从键盘中读取n写在while循…

文心一言,下一代模型开源

大家好&#xff0c;我是小悟。 百度官宣&#xff0c;将在未来几个月中陆续推出文心大模型 4.5 系列&#xff0c;并于 6 月 30 日起正式开源。 与此同时&#xff0c;百度近期发布多项 AI 开放政策&#xff0c;进一步降低大模型的使用门槛。随着文心大模型的迭代升级和成本不断…

排查生产sql查询缓慢

生产投产检验&#xff0c;发现查询客户明细的接口数据响应需要5秒以上&#xff0c;通过接口可以查询到详细的后端代码 1. 先排查后端的代码实现&#xff0c;并未出现复杂逻辑&#xff0c;那么就应该是sql的问题 2. 通过explain对sql进行解析&#xff0c;发现sql没有走索引 3.…

python脚本(一):飞书机器人实现新闻抓取与推送

根据飞书官方文档描述&#xff0c;可以在群组内增加飞书机器人来实现信息推送 自定义机器人使用指南 - 开发指南 - 开发文档 - 飞书开放平台 一、基于官方文档写一个基本文本推送的demo # feishu_notifier.py import requests import jsondef send_feishu_message(content, …

项目01--云备份

1.云备份初识 2.环境搭建--相关工具与库 若出现如下报错&#xff1a; 可尝试&#xff1a; 查看是否安装成功&#xff0c;注意安装下来的文件所在位置可能不同&#xff0c;使用时需注意 若无法用git clone连接上github网站可尝试直接在搜索引擎中登录该网站并查找bundle库&…

账号存活率骤降19%?2025跨境账号安全白皮书预警

账号安全危机来袭&#xff0c;跨境电商如何应对挑战&#xff1f; 在全球电商产业快速扩张的今天&#xff0c;账号安全问题日益严峻&#xff0c;尤其是在跨境电商领域。根据2025年《跨境账号安全白皮书》的报告&#xff0c;跨境电商平台账号存活率骤降19%&#xff0c;这一令人震…

Python迭代器知多少

目录 目标 Python版本 官方文档 概述 自定义可迭代对象 自定义迭代器 目标 掌握迭代器的使用方法。了解迭代器和可迭代对象的区别。通过案例实现迭代器和可迭代对象。 Python版本 Python 3.9.18 官方文档 迭代器https://docs.python.org/3.9/glossary.html#term-iterat…