C++ 构造函数与析构函数,与成员初始化列表语法

2023-12-21 10:20

本文主要是介绍C++ 构造函数与析构函数,与成员初始化列表语法,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

理论知识:C++构造函数与析构函数

关于函数有两个概念,函数的定义及函数的原型

//函数的原型
double sqrt(double);
//函数的定义
double sqrt(double x)
{..........
}

总结一句话:构造函数就是初始化,析构函数就是释放空间

(以上的函数,均需要有函数的原型及定义)

目录

1关于构造函数(类的初始化)

1.1explicit 

1.2默认构造函数(无参数)的原型及定义

 1.3构造函数和public&private

2关于析构函数(类的释放)

3new和delete对构造函数与析构函数的影响

4成员初始化列表(member initializer list)语法

5拷贝构造函数

5.1拷贝构造函数形式

5.2拷贝构造函数的调用时机

6深浅拷贝

7附录


1关于构造函数(类的初始化

  • 没有定义任何的构造函数时,编译器才会提供默认的构造函数
  • 当定义构造函数后,务必定义默认构造函数,否则报错。当定义对象时,如果主动使用构造函数没有初始化,那程序会自动调用默认构造函数
  • 构造函数不一定只有一个,但是有多个构造函数时,条件是每个函数的特征标各不同(构造函数支持函数重载)。

首先,说明如何声明及定义构造函数

同样的,构造函数也可以是private,当我们使用单例模式的时候,可以把类的构造函数声明成private的,这样就能保证外界不能实例多个对象出来了

构造函数书写要求:

  • 与类名相同
  • 无返回值
  • 不写void
  • 可以重载(可以有参数)

                          

//原型—— 位置:类定义public中
//构造函数的原型,此处只是举例子,并不是所有的构造函数的参数,都需要使用按引用传递
Stock(const std::string & co,long n = 0,double pr = 0.0);
//函数的定义——位置:类声明的公有部分
Stock::Stock(const string & co,long n,double pr)
{
company = co;if(n<0){..............}..........share_val = pr;..........
}

1.1explicit 

C++提供了关键字explicit(多数应用于只有一个参数的类构造函数),可以阻止不应该允许的经过转换构造函数进行的隐式转换的发生。声明为explicit的构造函数不能在隐式转换中使用。(不能被隐式地调用,只能显式地调用)

https://blog.csdn.net/guodongxiaren/article/details/24455653

explicit使用注意事项:

  1. explicit 关键字只能用于类内部的构造函数声明上。
  2. explicit 关键字作用于单个参数的构造函数(或者除了第一个参数外其余参数都有默认值的多参构造函数),如Circle(int x, int y = 0) 。
  3. 在C++中,explicit关键字用来修饰类的构造函数,被修饰的构造函数的类,不能发生相应的隐式类型转换,只能以显示的方式进行类型转换。
  4. 修饰拷贝构造函数后,禁止隐式调用拷贝构造函数。

 

explicit构造函数是用来防止隐式转换的。请看下面的代码:class Test1
{
public:Test1(int n){num=n;}//普通构造函数
private:int num;
};
class Test2
{
public:explicit Test2(int n){num=n;}//explicit(显式)构造函数
private:int num;
};
int main()
{Test1 t1=12;//隐式调用其构造函数,成功Test2 t2=12;//编译错误,不能隐式调用其构造函数Test2 t2(12);//显式调用成功return 0;
}

Test1的构造函数带一个int型的参数,代码(1)处会隐式转换成调用Test1的这个构造函数。而Test2的构造函数被声明为explicit(显式),这表示不能通过隐式转换来调用这个构造函数,因此代码(2)处会出现编译错误。
普通构造函数能够被隐式调用。而explicit构造函数只能被显式调用。

(来源:牛客网)

题目:


所以此处不能调用参数为int的构造函数。我认为此时编译器应该在所有带参构造函数中寻找适合的。因为上述中的n可以被转换为short,所以选择了参数是short的构造函数。 如果把参数short改为string,编译器就会报错,因为n转换不为string。 

1.2默认构造函数(无参数)的原型及定义

stock00.h
class Stock
{
private:std::string company;long shares;double share_cal;
public:void acquire(const std::string & co,long n,double pr);void buy(long num,double price);void sell(long num,double price);//函数声明中,参数可以相同,毕竟是按照参数传递而不是按值传递//默认构造函数方式的原型Stock();}
stock00.cpp
..........
//默认构造函数的定义
Stock::Stock()
{string company = "no name";shares = 0;share_cal = 0.0;
}
............

有些构造函数的原型中的参数也不一定非要是引用变量,下面这个可以作为参考

mytimee0.h
........
class Time
{
private:int hourse;int minutes;
public:Time();Time(int h,int m = 0);void AddMin(int m);void AddHr(int h);void Reset(int h = 0,int m = 0);Time sum(const Time & t) const;void show() const;
}

那么关于以上内容,在定义完对应类的对象时,我们应该如何使用呢?

显式调用构造函数(有等号)
Stock food = Stock("World Cabbage",250,1.25);
隐式调用构造函数(只有括号)
Stock garmet("Furry Mason",50,2.5);当然了,默认构造函数和构造函数都写了
那么就可以为所欲为的不进行调用
Stock frist;
Stock *pr = new Stock();
这个时候编译器会自动调用默认构造函数的

使用对象数组时,如何进行调用。

Stock my[4];//这就是对象数组
my[0].show();//show为Stock类中的公共接口
my[1].show();
//具体的调用过程
const int STKS = 4;
Stock stock[4] = {Stock("NanoSmart",12.5,20);Stock("Nanoscdasd",124.5,20);Stock( );
};
一共四个值,但是只调用了三个,前两个使用了构造函数,第三个使用了默认构造函数,第四个未出现的内容必然也是使用了默认构造函数。

 初始化对象数组的方案是,首先使用默认构造函数创建数组元素,然后花括号中的构造函数将创建临时对象,然后将临时对象的内容复制到相应的元素中。

除了上述的定义默认构造函数的方法,还有一种方法

构造函数和默认构造函数二合一一个函数原型一个函数定义

.........hStock(const std::string & co = “Error”,long n = 0,double pr = 0.0);//默认构造和构造函数一起
//以上形式使用了默认参数.........cppStock::Stock(const string & co,long n,double pr)
{
company = co;if(n<0){..............}..........share_val = pr;..........
}

目前来说,就以上内容,显示隐式调用构造函数还是和以前一样。调用默认构造函数就是就默认的值给相关的变量。 

 1.3构造函数和public&private

一般情况下,构造函数都是public,但是在单例模式下,比较特殊:

当我们想利用单例模式的时候,就可以把类的构造函数声明成private的,这样就能保证外界不能实例多个对象出来了。

 

下面看一个示例,关于构造函数的调用

题目1: 

MyClass c1,*c2;
MyClass *c3=new MyClass;
MyClass &c4=c1;

c1要调用一次构造函数;

c2只是一个指针,用来动态描述对象,不会调用类的构造函数;

c3的右边新创建一个对象会调用构造函数。但是注意,这里的赋值运算符不是类中的赋值运算符,而是普通的赋值运算符;

c4是一个对象引用,是c1的一个别名,所以不会调用构造函数。

(题目和解答都来自牛客网,@huixieqingchun

只要类的对象被创建,就会执行构造函数

c1,创建对象c1,调用了构造函数

c2,声明了一个指向MyClass类型的指针,未调用构造函数;

c3,new MyClass在内存中创建了一个对象,并把对象地址赋给指针c3,创建对象调用了构造函数

c4,将c4声明为引用,并将c1赋给它,即c4只是c1的一个引用,未调用构造函数。

2关于析构函数(类的释放)

  • ~类名
  • 无返回值
  • 不写void
  • 不可以重载(不可以有参数)
stock00.h
class Stock
{
private:std::string company;long shares;double share_cal;
public:void acquire(const std::string & co,long n,double pr);void buy(long num,double price);void sell(long num,double price);//析构函数原型~Shock();
}
stock00.cpp
//类声明
#include<iostream>
#include"stock.h"
//析构函数定义
Stock::~Stock()
{.....;//可以啥都没有//但是使用new分配空间时,记得使用delete释放//析构函数是和构造函数相对应的,当构造函数中使用new时,析构函数中需要使用delete进行删除
}

在类定义的过程中声明函数的原型,在类声明中进行函数的定义

  1. 如果创建的是静态存储类对象,则其析构函数就在程序完成代码时自动被调用
  2. 如何创建的是动态存储对象,则在其delete释放内存时,会被调用
  3. 如何创建的是自动存储对象,则在完成其代码段之后,会被调用

总结:关于析构函数是和构造函数是对应的,当类定义的对象要被释放时,就会调用相应的析构函数

我们下面看一个例子:

设已经有A,B,C,D4个类的定义,程序中A,B,C,D析构函数调用顺序为?

C c;
void main()
{A*pa=new A();B b;static D d;delete pa;
}

其中全局变量和静态局部变量时从 静态存储区中划分的空间,

二者的区别在于作用域的不同,全局变量作用域大于静态局部变量(只用于声明它的函数中),

而之所以是先释放 D 在释放 C的原因是, 程序中首先调用的是 C的构造函数,然后调用的是 D 的构造函数,析构函数的调用与构造函数的调用顺序刚好相反。

 

局部变量A 是通过 new 从系统的堆空间中分配的,程序运行结束之后,系统是不会自动回收分配给它的空间的,需要程序员手动调用 delete 来释放。

 

局部变量 B 对象的空间来自于系统的栈空间,在该方法执行结束就会由系统自动通过调用析构方法将其空间释放。

 

之所以是 先 A  后 B 是因为,B 是在函数执行到 结尾 "}" 的时候才调用析构函数, 而语句 delete a ; 位于函数结尾 "}" 之前

答案:

(来自牛客网:@老鼠)

以上题目很好的解释了,静态对象,动态对象和自动存储类对象析构函数的调用时机。

示例:

stock00.h
//类定义
class Stock
{
private:std::string company;long shares;double share_cal;
public:void buy(long num,double price);void sell(long num,double price);void update(double price);//默认构造函数的原型Stock();//构造函数的原型Stock(const std::string & co,long n = 0,double pr = 0.0);//析构函数的原型~Shock();
}
stock00.cpp
//类声明
#include<iostream>
#include"stock00.h"
//默认构造函数的定义
Stock::Stock()
{string company = "no name";shares = 0;share_cal = 0.0;
}
//构造函数的定义
Stock::Stock(const string & co,long n,double pr)
{
company = co;if(n<0){..............}..........share_val = pr;..........
}
//析构函数的定义
Stock::~Stock()
{.....;//可以啥都没有//但是使用new分配空间时,记得使用delete释放//析构函数是和构造函数相对应的,当构造函数中使用new时,析构函数中需要使用delete进行删除
}
//类中对应的公共接口的类对象,书写相应的功能即可
void Stock::buy(long num,double price)
{............ 
}
void Stock::sell(long num,double price)
{.............
}
void Stock::update(double price)
{.............
}usecjm.cpp//用户cpp
#include<iostream>
#include"stock00.h"
int main()
{using std::name;Stock stock1("Nam",12,20.0);//隐式调用构造函数Stock stock2 = Stock ("Bono",2,2.0);//显式调用构造函数stock1.updata();stock2.updata();
}

多个构造函数的情况(函数重载):

stonewt.h
........
class Stonewt
{
private:int stone;double pds_left;double pounds;
public:Stonewt(double lbs);//构造函数1Stonewt(int stn,double lbs);//构造函数2Stonewt();//默认构造函数~Stonewt();//析构函数void show_lbs();void show_stn();
};
#endif

上述内容有三个构造函数(两个构造函数一个默认构造函数)

分别是让用户定义一个浮点或两个浮点数,也可以直接创造Stonewt对象,而不进行初始化。

Stonewt blossem(132.5);//创建对象使用构造函数1
Stonewt buttercup(10,2);//创建对象使用构造函数2
Stonewt bubbles;//创建对象使用默认构造函数

3new和delete对构造函数与析构函数的影响

注意事项:

  1. 如果在构造函数中使用new来初始化指针成员,则应该在析构函数中使用delete
  2. new和delete必须相互兼容,new对应用delete,而new 【】 对应于delete 【】;
  3. 如果含有多个构造函数,则必须以相同的方式使用new,要么都带【】,要么都没有!因为只有一个析构函数,所有的构造函数中的new必须和析构函数中的delete匹配。

构造函数

Person::Person():Age(0),name("")
{qDebug()<<"进入构造函数";
}Person::Person(int i)
{qDebug()<<"int i,QString C_name 进入构造函数";Age = i;
}Person::Person(const int i,const QString C_name)
{qDebug()<<"int i,QString C_name 进入构造函数";Age = i;name = C_name;
}
Person::Person(const Person & p)
{qDebug()<<"const Person & p 进入构造函数";Age = p.Age;name = p.name;
}
Person::~Person()
{qDebug()<<"进入析构函数";}

cpp

MainWindow::MainWindow(QWidget *parent) :QMainWindow(parent),ui(new Ui::MainWindow)
{ui->setupUi(this);//查隐式类型转换test01();test00();
}
void test00()
{qDebug()<<"进入test00";Person * maxtrix = new Person[10];//堆区只能调用默认构造函数,所以使用new的时候务必确保有默认构造函数在Person max[3] = {Person(1),Person(1),Person(1)};//栈区可以调用其他类型的构造函数delete [] maxtrix;qDebug()<<"完成test00";}
void test01()
{qDebug()<<"进入test01";Person * new_p = new Person;delete new_p;qDebug()<<"完成test01";}

先看test00的输出

new为数组分配空间

类 * 变量名 = new 类[长度];

delete需要与之配套

delete [ ] 变量名;

在堆区,每次开辟一个空间,即会调用一次构造函数(且是默认构造函数),结束后即可释放。如maxtrix;

在栈区,可以选择其他带参数的构造函数。如max[]

再看test01的输出结果

test01中是给正常指针分配空间并delete

4成员初始化列表(member initializer list)语法

常规构造函数:
Quene::Quene(int qs)
{front = rear = NULL;item = 0;qsize = qs;
}
改进一下:
Quene::Quene(int qs):qsize(qs),front(NULL),rear(NULL),item(0) {}

注意,只有构造函数可以使用这种初始化列表的方法。

GraphModifier::GraphModifier(Q3DBars *bargraph): m_graph(bargraph),m_xRotation(0.0f),m_yRotation(0.0f),m_fontSize(30),m_segments(4),m_subSegments(3),m_minval(-20.0f),m_maxval(20.0f),//! [1]m_temperatureAxis(new QValue3DAxis),m_yearAxis(new QCategory3DAxis),m_monthAxis(new QCategory3DAxis),m_primarySeries(new QBar3DSeries),m_secondarySeries(new QBar3DSeries),//! [1]m_barMesh(QAbstract3DSeries::MeshBevelBar),m_smooth(false)
{//! [2]m_graph->setShadowQuality(QAbstract3DGraph::ShadowQualitySoftMedium);m_graph->activeTheme()->setBackgroundEnabled(false);m_graph->activeTheme()->setFont(QFont("Times New Roman", m_fontSize));m_graph->activeTheme()->setLabelBackgroundEnabled(true);m_graph->setMultiSeriesUniform(true);//! [2]m_months << "January" << "February" << "March" << "April" << "May" << "June" << "July" << "August" << "September" << "October" << "November" << "December";m_years << "2006" << "2007" << "2008" << "2009" << "2010" << "2011" << "2012" << "2013";

这是Qt中的一段程序,写的是构造函数,初值可以使用初始化列表进行,部分的内容是在构造函数内部进行初始化的。

没事儿可以看看Qt的示例,类写的太漂亮了。

5拷贝构造函数

用来举例的类:


class Person : public QMainWindow
{Q_OBJECTpublic:Person();explicit  Person(const int i);Person(const int i,const QString C_name);Person(const Person & p);~Person();int Age;QString name;static int a;static void func();};
Person::Person():Age(0),name("")
{qDebug()<<"进入构造函数";
}Person::Person(int i)
{qDebug()<<"int i,QString C_name 进入构造函数";Age = i;
}Person::Person(const int i,const QString C_name)
{qDebug()<<"int i,QString C_name 进入构造函数";Age = i;name = C_name;
}
Person::Person(const Person & p)
{qDebug()<<"进入拷贝构造函数";Age = p.Age;name = p.name;
}
Person::~Person()
{qDebug()<<"进入析构函数";
}

5.1拷贝构造函数形式

声明(函数原型)

Person(const Person & p);

定义

Person::Person(const Person & p)
{qDebug()<<"进入拷贝构造函数";Age = p.Age;name = p.name;
}

拷贝构造函数主要用于用已经初始化的对象初始未初始化的变量。当然还有其他用途,可见5.2 

C++标准中也规定,拷贝构造函数,不允许,按值传递,必须,按引用传递。

如果按值传递,参数需要在栈区开辟空间,赋值给参数,这个过程又会调用拷贝构造函数,形成递归,循环往复,直到崩溃。 

5.2拷贝构造函数的调用时机

拷贝构造函数发生在对象还没有创建,需要创建时,以下两种情况统一起来,就是这句话。

比如1的情况,p3还不存在,需要用p2去创建

再比如2的情况,形参p1还不存在,需要用p1去创建

当然了,当对象已经存在的情况下:

Person p1;
p1 = p2;

此时并不会调用拷贝构造函数。

1:用已经初始化的对象初始未初始化的变量

Person p3 = Person(p2);//显式调用 拷贝构造函数Person p4(2,"Test");Person p5(p4);//隐式调用 拷贝构造函数

2:以值传递的方式给函数参数传值

qDebug()<<"进入Copy_test";
Copy_test(p5);
qDebug()<<"完成Copy_test";    void Copy_test(Person p1)
{qDebug()<<"p.Age"<<p1.Age<<endl<<"p.Four"<<p1.name<<endl;
}

显然Copy_test 是按值传递,此时就会调用拷贝构造函数。

调用Copy_test函数,一开始会在栈区先分配空间给参数

调用拷贝构造函数,将p5的值拷贝给栈区的参数,之后在函数调用结束后,释放空间。输出内容如下: 

3:按值返回也会调用拷贝构造函数

传参,尤其是类或者结构体,尽量使用引用 const Person & p,和Person & Copy_test()....

 

相关题目:

#include<iostream>
using namespace std;
class MyClass
{
public:MyClass(int i = 0){cout << i;}MyClass(const MyClass &x){cout << 2;}MyClass &operator=(const MyClass &x){cout << 3;return *this;}~MyClass(){cout << 4;}
};
int main()
{MyClass obj1(1), obj2(2);MyClass obj3 = obj1;return 0;
}

答案:12244

 

解析1:@todd_nk(牛客网)

C MyClass obj3 = obj1;

obj3还不存在,所以调用拷贝构造函数输出2

如果obj3存在,obj3 = obj1,则调用复制运算符重载函数,输出3

6深浅拷贝

文章分享:

C++ -- 深浅拷贝 https://blog.csdn.net/xu1105775448/article/details/80546950

浅析C++中的深浅拷贝 https://blog.csdn.net/qq_39344902/article/details/79798297

 

7附录

默认构造函数,含参构造函数,拷贝构造函数,显式和隐式构造函数,成员初始化列表

#ifndef MAINWINDOW_H
#define MAINWINDOW_H#include <QMainWindow>
#include<QDebug>
namespace Ui {
class MainWindow;
}class MainWindow : public QMainWindow
{Q_OBJECTpublic:explicit MainWindow(QWidget *parent = 0);~MainWindow();private:Ui::MainWindow *ui;
};class Person : public QMainWindow
{Q_OBJECTpublic:Person();Person(const int i);explicit Person(const int i,const QString C_name);Person(const Person & p);//拷贝构造函数~Person();int Age;
//    int * Four;QString name;};
#endif // MAINWINDOW_H
#include "mainwindow.h"
#include "ui_mainwindow.h"MainWindow::MainWindow(QWidget *parent) :QMainWindow(parent),ui(new Ui::MainWindow)
{ui->setupUi(this);Person p;//调用默认构造函数qDebug()<<"p.Age"<<p.Age<<endl<<"p.Four"<<p.name<<endl;//显示调用Person p1 = Person();qDebug()<<"p1.Age"<<p1.Age<<endl<<"p1.Four"<<p1.name<<endl;Person p2 = Person(1,"cjm");qDebug()<<"p2.Age"<<p2.Age<<endl<<"p2.Four"<<p2.name<<endl;Person p3 = Person(p2);qDebug()<<"p3.Age"<<p3.Age<<endl<<"p3.Four"<<p3.name<<endl;//括号调用Person p4(2,"Test");qDebug()<<"p4.Age"<<p4.Age<<endl<<"p4.Four"<<p4.name<<endl;Person p5(p4);qDebug()<<"p5.Age"<<p5.Age<<endl<<"p5.Four"<<p5.name<<endl;}MainWindow::~MainWindow()
{delete ui;
}
Person::Person():Age(0),name("")
{qDebug()<<"进入构造函数";
}Person::Person(int i)
{qDebug()<<"int i,QString C_name 进入构造函数";Age = i;
}Person::Person(const int i,const QString C_name)
{qDebug()<<"int i,QString C_name 进入构造函数";Age = i;name = C_name;
}
Person::Person(const Person & p)
{qDebug()<<"const Person & p 进入构造函数";Age = p.Age;name = p.name;
}
Person::~Person()
{qDebug()<<"进入析构函数";}

 

 拷贝构造函数,即用已有值的对象初始化另外一个对象,参数是类,所以用引用,const为常规操作

这篇关于C++ 构造函数与析构函数,与成员初始化列表语法的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/519608

相关文章

深入理解C++ 空类大小

《深入理解C++空类大小》本文主要介绍了C++空类大小,规定空类大小为1字节,主要是为了保证对象的唯一性和可区分性,满足数组元素地址连续的要求,下面就来了解一下... 目录1. 保证对象的唯一性和可区分性2. 满足数组元素地址连续的要求3. 与C++的对象模型和内存管理机制相适配查看类对象内存在C++中,规

在 VSCode 中配置 C++ 开发环境的详细教程

《在VSCode中配置C++开发环境的详细教程》本文详细介绍了如何在VisualStudioCode(VSCode)中配置C++开发环境,包括安装必要的工具、配置编译器、设置调试环境等步骤,通... 目录如何在 VSCode 中配置 C++ 开发环境:详细教程1. 什么是 VSCode?2. 安装 VSCo

Python中列表的高级索引技巧分享

《Python中列表的高级索引技巧分享》列表是Python中最常用的数据结构之一,它允许你存储多个元素,并且可以通过索引来访问这些元素,本文将带你深入了解Python列表的高级索引技巧,希望对... 目录1.基本索引2.切片3.负数索引切片4.步长5.多维列表6.列表解析7.切片赋值8.删除元素9.反转列表

C++11的函数包装器std::function使用示例

《C++11的函数包装器std::function使用示例》C++11引入的std::function是最常用的函数包装器,它可以存储任何可调用对象并提供统一的调用接口,以下是关于函数包装器的详细讲解... 目录一、std::function 的基本用法1. 基本语法二、如何使用 std::function

JVM 的类初始化机制

前言 当你在 Java 程序中new对象时,有没有考虑过 JVM 是如何把静态的字节码(byte code)转化为运行时对象的呢,这个问题看似简单,但清楚的同学相信也不会太多,这篇文章首先介绍 JVM 类初始化的机制,然后给出几个易出错的实例来分析,帮助大家更好理解这个知识点。 JVM 将字节码转化为运行时对象分为三个阶段,分别是:loading 、Linking、initialization

【C++ Primer Plus习题】13.4

大家好,这里是国中之林! ❥前些天发现了一个巨牛的人工智能学习网站,通俗易懂,风趣幽默,忍不住分享一下给大家。点击跳转到网站。有兴趣的可以点点进去看看← 问题: 解答: main.cpp #include <iostream>#include "port.h"int main() {Port p1;Port p2("Abc", "Bcc", 30);std::cout <<

C++包装器

包装器 在 C++ 中,“包装器”通常指的是一种设计模式或编程技巧,用于封装其他代码或对象,使其更易于使用、管理或扩展。包装器的概念在编程中非常普遍,可以用于函数、类、库等多个方面。下面是几个常见的 “包装器” 类型: 1. 函数包装器 函数包装器用于封装一个或多个函数,使其接口更统一或更便于调用。例如,std::function 是一个通用的函数包装器,它可以存储任意可调用对象(函数、函数

hdu1171(母函数或多重背包)

题意:把物品分成两份,使得价值最接近 可以用背包,或者是母函数来解,母函数(1 + x^v+x^2v+.....+x^num*v)(1 + x^v+x^2v+.....+x^num*v)(1 + x^v+x^2v+.....+x^num*v) 其中指数为价值,每一项的数目为(该物品数+1)个 代码如下: #include<iostream>#include<algorithm>

C++11第三弹:lambda表达式 | 新的类功能 | 模板的可变参数

🌈个人主页: 南桥几晴秋 🌈C++专栏: 南桥谈C++ 🌈C语言专栏: C语言学习系列 🌈Linux学习专栏: 南桥谈Linux 🌈数据结构学习专栏: 数据结构杂谈 🌈数据库学习专栏: 南桥谈MySQL 🌈Qt学习专栏: 南桥谈Qt 🌈菜鸡代码练习: 练习随想记录 🌈git学习: 南桥谈Git 🌈🌈🌈🌈🌈🌈🌈🌈🌈🌈🌈🌈🌈�

【C++】_list常用方法解析及模拟实现

相信自己的力量,只要对自己始终保持信心,尽自己最大努力去完成任何事,就算事情最终结果是失败了,努力了也不留遗憾。💓💓💓 目录   ✨说在前面 🍋知识点一:什么是list? •🌰1.list的定义 •🌰2.list的基本特性 •🌰3.常用接口介绍 🍋知识点二:list常用接口 •🌰1.默认成员函数 🔥构造函数(⭐) 🔥析构函数 •🌰2.list对象