湖北省建设厅网站查询网络营销的四种形式
#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;
 }
 
