C++的类与对象(三):构造函数、析构函数、对象的销毁顺序

目录

类的6个默认成员函数

构造函数

语法

特性

析构函数

特性

对象的销毁顺序​​​​​​​​​​​​​​


类的6个默认成员函数

问题:一个什么成员都没的类叫做空类,空类中真的什么都没有吗?

基本概念:任何类在什么都不写时,编译器会自动生成以下六个默认成员函数(无参的)

定义:用户没有显式实现,编译器会生成的成员函数称为默认成员函数

注意事项:如果我们自己实现了这些函数,那么编译器就不会生成默认的成员函数 

构造函数

产生原因:初始化容易被遗忘,且有时候会太麻烦

作用:完成初始化工作(Init)

class Date
{
public:
     void Init(int year, int month, int day)
     {
         _year = year;
         _month = month;
         _day = day;
     }

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

private:
     int _year;
     int _month;
     int _day;
};

int main()
{
 Date d1;
 d1.Init(2022, 7, 5);
 d1.Print();
 Date d2;
 d2.Init(2022, 7, 6);
 d2.Print();
 return 0;
}

        对于Data类,之前我们会通过Init公有方法给对象设置日期,但每次创建对象时都需要调用该方法设置信息就显得有点麻烦,C++的构造函数就可以做到在对象创建时,就将信息设置进去

语法

1、构造函数是特殊的成员函数

2、构造函数的主要任务是在类实例化对象时初始化对象,而不是去开空间创建对象

3、构造函数的函数名与所在类的类名相同(类名是A,构造函数的名字就叫A,客随主便)

4、构造函数无返回值(不是void,而是连void都没)

5、对象实例化时编译器会自动调用合适的构造函数(对象后没括号就调无参构造函数,有实参就调用带参构造函数)

#include <iostream>
using namespace std;

 class Date
 {
  public:
      // 1.无参构造函数
      Date()
     {
        _year = 1;
        _month = 1;
        _day = 1;
     }

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

  private:
      int _year;
      int _month;
      int _day;
 };

int main()
{
    Date d1; // 调用无参构造函数
    d1.Print();
    return 0;
}

6、构造函数可以重载

#include <iostream>
using namespace std;

class Date
{
public:
    // 1.无参构造函数
    Date()
    {
        _year = 1;
        _month = 1;
        _day = 1;
    }
    void Print()
    {
        cout << _year << "-" << _month << "-" << _day << endl;
    }
    // 2.带参构造函数
    Date(int year, int month, int day)
    {
        _year = year;
        _month = month;
        _day = day;
    }
private:
    int _year;
    int _month;
    int _day;
};

int main()
{
    Date d1; // 调用无参构造函数
    d1.Print();

    Date d2(2015, 1, 1); // 调用带参的构造函数
    d2.Print();
    return 0;
}

7、构造参数没有形参时,对象实例化时不能在对象后加括号

8、 对象实例化时必须调用构造函数,没有或者没有合适的构造函数就会报错(d1原本想要调用无参的构造函数,但是只有带参的构造函数,有了带参的构造参数编译器就算像提供不带参的默认构造参数也没办法了)

#include <iostream>
using namespace std;

class Date
{
public:
    void Print()
    {
        cout << _year << "-" << _month << "-" << _day << endl;
    }

    //带参构造函数
    Date(int year, int month, int day)
    {
        _year = year;
        _month = month;
        _day = day;
    }

private:
    int _year;
    int _month;
    int _day;
};

int main()
{
    Date d1;
    d1.Print();
    return 0;
}

9、无参的构造函数和全缺省的构造函数在语法上因为函数重载可以同时存在,但是在实践中不可以,会造成调用歧义

#include <iostream>
using namespace std;

class Date
{
public:

    Date()
    {
        _year = 1;
        _month = 1;
        _day = 1;
    }
    void Print()
    {
        cout << _year << "-" << _month << "-" << _day << endl;
    }

    Date(int year = 1, int month = 1, int day = 1)
    {
        _year = year;
        _month = month;
        _day = day;
    }
private:
    int _year;
    int _month;
    int _day;
};

int main()
{
    Date d1;
    d1.Print();
    return 0;
}

特性

1(重点)、实例化对象时我们不写构造函数(包括默认构造函数和普通的构造函数),编译器就会生成默认构造函数,从而初始化对象,我们写了构造参数编译器就不会生成默认构造参数(普通的构造参数是指带参的构造参数)

2、编译器生成的默认构造参数什么也不干,为什么?(我们程序员没有定义一个构造参数是我们的问题,但是你编译器既然为我们自动生成了一个默认构造参数,你总得让它起点作用吧,就是只让成员变量初始化为0也行啊)

#include <iostream>
using namespace std;

class Date
{
public:
    void Print()
    {
        cout << _year << "-" << _month << "-" << _day << endl;
    }

private:
    int _year;
    int _month;
    int _day;
};

int main()
{
    Date d1;
    d1.Print();
    return 0;
}

这是因为,C++将数据分为了内置(基本)类型和自定义类型:

  • 内置类型:语言自身定义的类型(int、char、double、任何类型的指针等)
  • 自定义类型:程序员根据自己需求定义的类型(struct、class等)

3、C++98规定编译器生成的默认构造函数(程序员没提过时),对内置类型不做处理,对自定义类型会去调用它的!!默认构造函数!!(一定是默认构造函数而不是普通的构造函数)

#include <iostream>
using namespace std;

//编译器对自定义类型会调用它的默认构造
class A
{
public:
    A()
    {
        cout << "A()" << endl;
        _a = 0;
    }
private:
    int _a;

};

//编译器对内置类型不做处理
class Date
{
public:

//这里没有自定义构造函数,编译器默认生成构成函数

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

private:
    int _year;
    int _month;
    int _day;

    A _aa;
};

int main()
{
    Date d1;
    d1.Print();
    return 0;
}

大致步骤如下:
①Date d1:实例化对象d1

②Data{}:编译器自动生成默认构造函数,并开始对成员变量开始初始化 

③__aa:_aa的类型是A类,属于自定义类型,调用A类的提供的!默认!构造函数

如果A类也没提供默认构造函数,那么_aa也是随机值(虽然编译器也可以为A提供但是没用):

#include <iostream>
using namespace std;

class A
{
public:
    int getA() // 添加一个公共方法以获取 _a 的值
    {
        return _a;
    }

private:
    int _a;

};

class Date
{
public:

    void Print()
    {
        cout << "Year: " << _year << ", Month: " << _month << ", Day: " << _day << endl;
        cout << "Value of '_aa' member variable in class 'Date': " << _aa.getA() << endl; // 打印_aa对象内部_a变量的值
    }

private:
    int _year;
    int _month;
    int	_day;

    A _aa;
};


int main()
{
    Date d1;
    d1.Print();
    return 0;
}

④_year、_month、_day:是int类型,属于内置类型,不做任何操作,结果为随机值

为什么在调试时,先初始化对象_aa?

答:C++中,类的成员变量初始化顺序是由它们在类中声明的顺序决定的,而不是由它们在构造函数初始化列表中出现的顺序决定

注意事项:有些新的编译器会对内置类型也做处理,但是C++的标准没有规定 

4、C++11规定内置类型的成员变量声明时可给默认值(为C++98打补丁,没给的依然是随机值)

#include <iostream>
using namespace std;

class A
{
public:
    A()
    {
        cout << "A()" << endl;
        _a = 0;
    }

private:
    int _a;

};

class Date
{
public:
    void Print()
    {
        cout << _year << "-" << _month << "-" << _day << endl;
    }

private:
    //声明时给缺省值
    int _year = 2024;
    int _month =3 ;
    int _day;

    A _aa;
};

int main()
{
    Date d1;
    d1.Print();
    return 0;
}

5、 只有无参 / 全缺省构造函数、编译器默认生成的构造函数都叫默认构造函数,其余的都是构造函数而不是默认构造函数,默认构造函数只能有一个 

//默认构造参数只能有一个:
#include <iostream>
using namespace std;
class Date
{
public:
    //无参的构造函数是默认构造函数
    Date()
    {
        _year = 1900;
        _month = 1;
        _day = 1;
    }

    //全缺省的构造函数是默认构造函数
    Date(int year = 1900, int month = 1, int day = 1)
    {
        _year = year;
        _month = month;
        _day = day;
    }
private:
    int _year;
    int _month;
    int _day;
};

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

//成员变量在声明时未给缺省值
#include <iostream>
using namespace std;
class Date
{
public:

    Date(int year = 1, int month , int day)
    {
        _year = year;
        _month = month;
        _day = day;
    }

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

     ~Date()
    {
         cout << this << endl;
         cout << " ~Date()" << endl;
    }

private:
    int _year;
    int _month;
    int _day;

};

int main()
{
    Date d1;
    d1.Print();

    return 0;
}

//成员变量在声明时提供缺省值:
#include <iostream>
using namespace std;
class Date
{
public:

    Date(int year = 1, int month , int day)
    {
        _year = year;
        _month = month;
        _day = day;
    }

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

     ~Date()
    {
         cout << this << endl;
         cout << " ~Date()" << endl;
    }

private:
    int _year = 1;
    int _month = 1;
    int _day =1;
};

int main()
{
    Date d1;
    d1.Print();
    return 0;
}

为什么成员变量在声明时已经给了缺省值,为什么Data还要再给?

虽然为 Date 类中的私有成员变量 _year_month, 和 _day 提供了默认值(1, 1, 1),但这些缺省值仅在默认构造函数未初始化成员变量时才会被用于初始化成员变量。实例化d1时,类中定义了一个貌似是全缺省的构造函数,因此编译器不会自动生成默认构造函数(那个位置上已经有人了,只是那个人有点缺陷),且因为该貌似的全缺省构造函数缺少两个缺省值所以报错

#include <iostream>
using namespace std;

class Time
{
public:
    //带参构造函数,不是默认构造函数
    Time(int hour)
    {
        cout << "Time()" << endl;
        _hour = 0;
        _minute = 0;
        _second = 0;
    }
private:
    int _hour;
    int _minute;
    int _second;
};

class Date
{
private:
    //声明给缺省值
    int _year;
    int _month;
    int _day;

    Time _t;
};

int main() 
{
    Date d;
    return 0;
}

为什么会提示_t没有默认构造函数?

答:实例化对象d时,Date类没给构造函数,编译器自动生成默认构造函数(无参),_year、_month、_day是内置类型不做处理,_t是自定义类型会调用Time类的默认构造函数,但是Time类中已经有了一个带参的构造函数(普通构造函数)所以Time类中不会有默认构造函数了(只要我们写了构造函数,即使它是带参的普通构造函数,编译器就不会给我们提供默认构造参数了)故报错

 结论:绝大多数场景下都需要自己实现构造函数,且更推荐用全缺省构造函数​​​​​​​

析构函数

 产生原因:需要人为销毁的空间容易忘记销毁,内存泄漏可能不会报错

#include <iostream>
using namespace std;
class Date
{
public:
    void Print()
    {
        cout << _year << "-" << _month << "-" << _day << endl;
    }

    ~Date()
    {
        cout << this << endl;
        cout << " ~Date()" << endl;
    }

private:
    //声明给缺省值
    int _year = 1;
    int _month = 1;
    int _day = 1;

};

void func()
{
    Date d2;
}

class Stack
{
public:
    Stack(size_t capacity = 4)
    {
        _array = (int*)malloc(sizeof(int*) * capacity);
        if (NULL == _array)
        {
            perror("malloc申请空间失败!!!");
            return;
        }
        _capacity = capacity;
        _size = 0;
    }
    void Push(int data)
    {
        // CheckCapacity();
        _array[_size] = data;
        _size++;
    }

    //~Stack()
    //{
    //    cout << "~Stack()" << endl;
    //    if (_array)
    //    {
    //        free(_array);
    //        _array = nullptr;
    //    }
    //    _size = _capacity = 0;

    //}

private:
    int* _array;
    int _capacity;
    int _size;
};

int main()
{
    func();
    Date d1;
    Stack st1; //内存泄漏
    return 0;
}

        如果Stack类中没有自定义的析构函数就会出现内存泄漏,因为我们即没有定义Destory函数去销毁在堆上开辟的空间,析构函数也不起作用

作用:完成清理工作(Destory)

基本概念:析构函数不是完成对对象本身的销毁,局部对象销毁工作是由编译器完成的,而对象在销毁时会自动调用析构函数,完成对象中资源的清理工作

特性

1、析构函数名是在类名前加上字符~

2、析构函数无参数无返回值类型

3、一个类只能有一个析构函数,若未显示定义,编译器会自动生成默认的析构函数

4、析构函数不能重载(清理一遍数据就应该被清理完成)

5、对象生命周期结束(函数结束)时,程序会自动调用析构函数

#include <iostream>
using namespace std;
class Date
{
public:

     ~Date()
    {
         cout << this << endl;
         cout << " ~Date()" << endl;
    }

private:
    //声明给缺省值
    int _year = 1;
    int _month = 1;
    int _day =1;
};

void func()
{
    Date d2;//实例化对象d2
}//函数结束,调用析构函数销毁数据

int main()
{
    func();  
    Date d1;//实例化对象d1
    return 0;
}//函数结束,调用析构函数销毁数据

6、编译器生成的析构函数,对内置成员变量不做处理,对自定成员变量会调用它的析构函数

#include <iostream>
using namespace std;

class Time
{
public:
	~Time()
	{
		cout << "~Time()" << endl;
	}
private:
	int _hour;
	int _minute;
	int _second;
};

class Date
{
private:
	// 基本类型(内置类型)
	int _year = 1970;
	int _month = 1;
	int _day = 1;
	// 自定义类型
	Time _t;
};
int main()
{
	Date d;
	return 0;
}

在main函数中没有直接创建Time类的对象,为什么最后会调用Time类的析构函数?

答:main函数中创建了Date类的对象d,d中包含了四个成员变量,其中_year、_month、_day是内置类型的成员变量,销毁时不需要人为清理资源main函数结束后系统直接回收,而_t是Time类的对象,为了销毁_t就需要Data类的析构函数,但是我们并没有给Date类定义析构函数,所以编译器就会为Date类提供一个默认析构函数,该函数对于自定义类型的成员变量就会调用它(_t)的析构函数(Time提供的析构函数)

7、后定义的先析构(定义->开辟帧栈->压栈,栈后进先出)

#include <iostream>
using namespace std;
class Date
{
public:
    ~Date()
    {
        cout << this << endl;
        cout << " ~Date()" << endl;
    }

private:
    //声明给缺省值
    int _year = 1;
    int _month = 1;
    int _day = 1;

};

class Stack
{
public:
    Stack(int capacity = 4)
    {
        _array = (int*)malloc(sizeof(int*) * capacity);
        if (NULL == _array)
        {
            perror("malloc申请空间失败!!!");
            return;
        }
        _capacity = capacity;
        _size = 0;
    }
    void Push(int data)
    {
        // CheckCapacity();
        _array[_size] = data;
        _size++;
    }

    ~Stack()
    {
        cout << this << endl;
        cout << "~Stack()" << endl;
        if (_array)
        {
            free(_array);
            _array = nullptr;
        }
        _size = _capacity = 0;

    }
private:
    int* _array;
    int _capacity;
    int _size;
};

int main()
{
    Date d1;
    Stack st1;
    return 0;
}

 8、如果类中没有申请资源时,析构函数可以不写,直接使用编译器生成的默认析构函数(Date类);有资源申请时,一定要写,否则会造成资源泄漏(Stack类)

 9、自定义类型的本质还是内置类型

对象的销毁顺序

从左至右:局部变量(后定义的先析构)——>局部的静态——>全局(后定义的先析构)

当成栈来理解,先进后出 

#include <iostream>
using namespace std;
class Date
{
public:
    //全缺省构造函数
    Date(int year = 1)
    {
        _year = year;
    }

    ~Date()
    {
        cout << " ~Date()->" << _year << endl;
    }

private:
    //声明给缺省值
    int _year;
    int _month;
    int _day;

};

Date d5(5);//全局
Date d6(6);//全局
static Date d7(7);//全局
static Date d8(8);//全局

void func()
{
    Date d3(3);//局部
    static Date d4(4);//局部的静态
}

int main() 
{
    Date d1(1);//局部
    Date d2(2);//局部
    func();
    return 0;
}


#include <iostream>
using namespace std;
class Date
{
public:
    //全缺省构造函数
    Date(int year = 1)
    {
        _year = year;
    }

    ~Date()
    {
        cout << " ~Date()->" << _year << endl;
    }

private:
    int _year;
    int _month;
    int _day;

};

int main()
{
    Date d1(1);//局部
    Date d2(2);//局部
    static Date d3(3);//局部的静态
    return 0;
}


~over~

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mfbz.cn/a/446204.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

[MRCTF2020]Transform1

a[33]"9,10,15,23,7,24,12,6,1,16,3,17,32,29,11,30,27,22,4,13,19,20,21,2,25,5,31,8,18,26,28,14" b[33]"103,121,123,127,117,43,60,82,83,121,87,94,93,66,123,45,42,102,66,126,76,87,121,65,107,126,101,60,92,69,111,98,77" python代码 a3 [103…

three.js 射线Ray,三维空间中绘制线框

效果&#xff1a; 代码&#xff1a; <template><div><el-container><el-main><div class"box-card-left"><div id"threejs"></div> <div>{{ res1 }}</div> <div>{{ res2 }}</div><…

一图看懂Redis持久化机制!

持久化策略 Redis 提供了两种持久化策略&#xff1a; RDB (Redis Database Snapshot) 持久化机制&#xff0c;会在一段时间内生成指定时间点的数据集快照(snapshot) AOF&#xff08;Append Only File&#xff09; 持久化机制&#xff0c;记录 server 端收到的每一条写命令&am…

nmcli绑定bond双网卡(active-backup模式)

安装包 apt-get install network-manager apt install net-tools当前网卡mac地址IP都不一样 创建名为“jbl”的新连接&#xff0c;并将其模式设置为“active-backup” nmcli connection add type bond ifname jbl mode active-backup添加物理网卡到bond(JBL),两个物理网卡添加…

linux操作系统虚拟机的环境配置

目录 一、虚拟机安装&#xff08;类似硬件的安装&#xff09; &#xff08;1&#xff09;创建虚拟机 &#xff08;2&#xff09;创建虚拟机 二、IP和主机名称配置 1、设置VM上的IP 2、设置我们电脑上VMnet8的IP 3、设置虚拟机上的IP 主机名称映射 以下是设置主机名映射…

【异常处理】sbt构建Chisel库时出现extracting structure failed:build status:error的解决办法

文章目录 报错背景&#xff1a;解决思路&#xff1a;①IDEA中配置本地的SBT进行下载②更改下载源为华为的镜像站1. 修改sbtconfig.txt2. 增加repositories文件 ③查看报错信息 总结整理的Scala-Chisel-Chiseltest版本信息对应表 报错背景&#xff1a; 最近在写Chisel时&#x…

JavaScript基础5之作用域、执行上下文的顺序执行、可执行代码、执行上下文栈

JavaScript基础 作用域思考 执行上下文顺序执行可执行代码执行上下文栈案例一案例二case1:case2 作用域 作用域&#xff1a;程序源代码中定义变量的区域。作用域规定了如何查找变量&#xff0c;也就是确定当前执行代码对变量的访问权限。作用域分类&#xff1a;静态作用域&…

哈希表|242.有效的字母异位词

力扣题目链接 bool isAnagram(char* s, char* t) {int len_s strlen(s), len_t strlen(t);if(len_s ! len_t) {return false;}int table[26];memset(table, 0, sizeof(table));for(int i 0; i < len_s; i) {table[s[i] - a];}for(int i 0; i < len_t; i) {table[t[i…

二,几何相交---4,BO算法---(1)接近性和可分离性

提了三个观点 1&#xff0c;如果一条直线&#xff08;比如竖直&#xff09;可以分开两个线段&#xff0c;则这两个线段不相交 2&#xff0c;只需要观察与隔离线相交的几个线段 3&#xff0c;从左向右扫描线只需要观察每个线段的两个端点和一些可能的相交点。

2024年【化工自动化控制仪表】新版试题及化工自动化控制仪表考试试题

题库来源&#xff1a;安全生产模拟考试一点通公众号小程序 化工自动化控制仪表新版试题是安全生产模拟考试一点通总题库中生成的一套化工自动化控制仪表考试试题&#xff0c;安全生产模拟考试一点通上化工自动化控制仪表作业手机同步练习。2024年【化工自动化控制仪表】新版试…

Qt 中Json文件的操作

Json文件的读取 QFile file("data.json"); //准备好的文件file.open(QIODevice::ReadOnly|QIODevice::Text);QByteArray arr file.readAll();QJsonDocument jsonDoc QJsonDocument::fromJson(arr);QJsonObject jsonObj jsonDoc.object();qint32 id jsonObj["…

沁恒蓝牙芯片CH582:蓝牙OTA升级技术详解与应用探索

文章目录 一、前言1.WCH 蓝牙空中升级&#xff08;BLE OTA&#xff09;概述2. WCH BLE SDK DFU 工作原理&#xff08;方式一&#xff09; 二、移植程序1.找到BackUpgrade_OTA例程2.添加文件到工程2.1 添加文件2.2 如何添加 3.修改APP工程3.1 修改peripheral_main.c文件3.2 修改…

Leetcode 59.螺旋矩阵Ⅱ

1.题目 2.思路 &#xff08;借用代码随想录的图&#xff09; 1.我们将转一圈看作一个循环&#xff08;1->2->3->4->5->6->7->8 这是一个循环&#xff09; 2.在这个循环里&#xff0c;我们要画四条边&#xff08;上右下左&#xff09; 填充上行从左到右 填…

数据分析-Pandas画分布密度图

数据分析-Pandas画分布密度图 数据分析和处理中&#xff0c;难免会遇到各种数据&#xff0c;那么数据呈现怎样的规律呢&#xff1f;不管金融数据&#xff0c;风控数据&#xff0c;营销数据等等&#xff0c;莫不如此。如何通过图示展示数据的规律&#xff1f; 数据表&#xff…

前后端分离项目,如何解决跨域问题?

跨域问题是前后端分离项目中非常常见的一个问题&#xff0c;举例来说&#xff0c;编程猫学习网站的前端服务跑在 8080 端口下&#xff0c;后端服务跑在 9002 端口下&#xff0c;那么前端在请求后端接口的时候就会出现跨域问题。 403 Forbidden 是HTTP协议中的一个状态码&#x…

编曲学习:钢琴编写 人性化、逻辑预制 工程音频导出

第8课 钢琴编写 人性化、逻辑预制 工程音频导出小鹅通-专注内容付费的技术服务商https://app8epdhy0u9502.pc.xiaoe-tech.com/live_pc/l_65e30339e4b064a8cfe56001?course_id=course_2XLKtQnQx9GrQHac7OPmHD9tqbv 音乐创作中,有思路时可以不套学习到的公式,没有思路时可以套…

VMware下载与安装

准备一个Linux的系统&#xff0c;成本最低的方式就是在本地安装一台虚拟机&#xff0c;VMware是业界最好用的虚拟机软件之一 官网&#xff1a;https://www.vmware.com/ 下载页面&#xff1a;https://www.vmware.com/products/workstation-pro/workstation-pro-evaluation.html …

前端学习之列表标签

目录 有序列表 结果 无序标签 结果 数据标签 结果 有序列表 &#xff08;注&#xff1a;注释是解释&#xff09; <!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><title>Document</title> </…

MySQL数据库管理

本章内容&#xff1a; 掌握数据库的查看方法掌握MySQL 库和表的创建和删除方法掌握MySQL 增删改查常见操作掌握MySQL 用户权限 1.1使用MySQL数据库 在熟悉安装及访问MySQL 数据库以后&#xff0c;接下来将学习MySQL 数据库的基本操作&#xff0c; 这也是在服务器运维工作工不…

windows使用pyenv

1、前言 虽然anaconda比pyenv相比有更好的python安装体验&#xff0c;但是有一个比较严重的问题的就是&#xff0c;他的python版本跨度不够大&#xff0c;一些老一些的项目的python版本找不到&#xff0c;比如py12306要求的python版本是3.6&#xff0c;在anaconda却找不到这个版…