C++类和对象系列文章目录
提示:C++类和对象的基础知识点,后续再补充
文章目录
- C++类和对象系列文章目录
- 1.1C和C++中的结构体struct
- 1.2 类声明和变量分离
- 1.3 类的封装
- 1.4 类外使用成员函数 在类外使用::作用域解析符来指明成员属于哪个类
- 1.5 声明和定义的拓展
- 1.6 对象中只会存储成员变量,而不会存储成员函数。why?
- 1.7 类对象中隐含的this指针
- 1.8 构造函数:初始化对象
- 1.9 无参的构建函数和全缺省构造函数
- 1.10 析构函数
- 1.11 拷贝构造 :采用同类对象来构造新的对象
- 1.12 运算符重载
- 1.13 const如何修饰this指针
- 1.14 关于类中const权限无法放大的应用
- 1.15 初始化列表 与 成员变量的声明和定义
- 1.16 类中的 static成员变量和static成员函数
- 1.18 数组对象 Data a[10]; 会调用10次构造函数
- 1.19 类中声明时给缺省
- 1.20 有元函数
- 1.21 有元类
- 1.22 内存基础知识
- 1.23 C++的动态内存(堆上空间)管理 new delete
- 1.24 operator new(不调用构造)和new(调用构造) operator delete(不调用析构) 和delete(调用析构)
- 1.25 A=B的返回值是A
- 1.26 定位new
- 1.27 模版template 兼容任何类型的代码 函数模版
- 1.28 类模版
- 1.29 模版底层原理
- 1.30 匿名对象 对象名();
1.1C和C++中的结构体struct
在 C 语言中,结构体主要用于定义数据类型,主要用来组合不同类型的变量。然而,在 C++ 中,结构体的功能得到了扩展,不仅可以定义变量,还可以定义成员函数。因此,C++ 中的结构体实际上可以视为一种特殊的类。
C vs C++ 中的结构体
-
C 语言:
- 结构体只能用于定义数据类型和变量。
- 结构体的功能相对简单,主要用于数据的组合。
-
C++ 语言:
- 结构体可以定义变量和成员函数。
- 支持访问修饰符(如
public和private),使得结构体的封装性更强。 - 可以进行继承和多态,进一步增强了其功能。
因此,虽然 C++ 中的结构体在某些方面与类相似,但由于它们在默认访问控制和用途上的一些区别,仍然可以将其称为结构体。
struct Student
{
void SteStudentInfo(const char* name,const char* gender,int age)
{
strcpy(_name,name);
strcpy(_gender,gender);
_age = age;
}
void printStudentInfo()
{
cout<<_name<<" "<<_gender<<" "<<_age<<endl;
}
char _name[20];
char _gender[3];
int _age;
};
虽然结构体和类在功能上有很多相似之处,但 C++ 专门定义了 class 来实现面向对象编程,以提供更严格的封装和访问控制。这使得开发者可以更好地管理数据和功能,促进代码的重用和维护。
1.2 类声明和变量分离
person.h 文件中
class Person
{
public:
void ShowInfo();
private:
char* _name;
char* _sex;
int _age;
};
person.cpp文件中
#inclde "person.h"
void Person::showInfo()
{
cout<<_name<<"_"<<_sex<<"_"<<_age<<_endl;
}
1.3 类的封装
public(公有) 类外也可以访问
protected(保护)和private(私有)类外无法访问
class默认访问权限:私有 private
struct默认访问权限:共有 public 兼容C
1.4 类外使用成员函数 在类外使用::作用域解析符来指明成员属于哪个类
class Person
{
public:
void ShowInfo();
private:
char* _name;
char* _sex;
int _age;
};
void Person::showInfo() //成员函数类外需要指明所属类
{
cout<<_name<<"_"<<_sex<<"_"<<_age<<_endl;
}
1.5 声明和定义的拓展
声明是一种承诺,其不分配空间;
定义是对象的实例化,分配空间;
声明可以多次,但是定义只能一次
声明可以在多个源文件中,通过#ifndef来解决,而定义只能在一个源文件中。
1.定义的情况
万物皆可以对象
类名 对象名;(数据类型 变量) +函数定义
```cpp
int x; //变量定义 分配空间
Person p; //对象定义 分配空间
int Add(int x,int y) //函数定义 分配栈空间
{
return x+y;
}
1.声明的情况
extern int x;
(extern) int Add(intx,int y);
1.6 对象中只会存储成员变量,而不会存储成员函数。why?
在 C++ 中,一个类可以实例化出多个对象,这些对象的成员函数相同,但它们的成员变量值各异。为了节省空间,成员变量存储在每个对象实例中,而成员函数则存储在公共代码区中。
注意:如果一个空对象有一个字节的空间,why,占位,方便取地址。
1.7 类对象中隐含的this指针
1.this指针指向 谁调用指向谁, this指针是类中的成员函数的第一个参数
2.this指针不能为空,空的this,会导致 this->变量是报错
class Date
{
public:
void Init(int year,int month,int day)
{
_year = year;
_month =month;
_day = day;
}
>>>>>>>>>>>>>>>>编译器编译为>>>>>>>>>>>>>>>>>>
void Init(Data* this,int year,int month,int day)
{
this->_year = year;
this->_month =month;
this->_day = day;
}
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
private:
int _year;
int _month;
int _day;
};
int mian()
{
Date d1;
d1.Init(2020,4,7)//
>>>>>>>>>>>>>>>>编译器编译为>>>>>>>>>>>>>>>>>>
d1.Init(&d1,2020,4,7);
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
}
1.8 构造函数:初始化对象
1.函数名和类名一样
2.无返回值
3.对象实例化时自动调用
4.构造函数可以重载
5.如果未定义构造函数,编译器会自动生成一个无参的默认构造函数
6.默认的析构在定义对象 会随机初始化内置类型的值
对于自定义类型 会调用对于的构造函数
class Time
{
public:
Time() //构造函数 函数名和类名一样 无返回值
{
_hour = 0;
_minute = 0;
_second =0;
}
private:
int _hour;
int _minute;
int _second;
};
class Date
{
void Print()
{
cout<<_year<<"_"<<_month<<"_"<<_day<<endl;
}
private:
int _year;
int _month;
int _day;
Time _t;
};
int main()
{
Date d1;
//定义对象d1时,
对象空间会创建变量int _year int _month int _day 这些对调用g++编译器生成的构造函数初始化为随机值
而创建自定义类型Time _t ,也相当于实例化Time类,会自动调用Time的构造函数,使得_t._hour = 0;_t._minute = 0;_t._second =0;
d1.Print();
//_year 随机值
//_month
return 0;
}
1.9 无参的构建函数和全缺省构造函数
为了兼容 Data d1;和Data d1(2020,4,6);这二种写法
可以采用函数重载来实现,但需要写二个函数
class Date
{
public:
Date(int year,int month,int day)//兼容Data d1(2020,4,6);
{
_year = year;
_month =month;
_day = day;
}
Date()//兼容Data d1;
{
_year = 0;
_month =0;
_day = 0;
}
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
采用全缺省构造函数可以合二为一
Date(int year=0,int month=0,int da=0)//兼容Data d1(2020,4,6);和//Data d1;
{
_year = year;
_month =month;
_day = day;
}
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
private:
int _year;
int _month;
int _day;
};
1.10 析构函数
对象什么周期到了,自动调用,用来清理和释放空间资源。
1.函数名为 ~类名
2.无参 无返回值
3.一个类只有一个析构函数
4.未定义,编译器会自动生成一个默认析构函数
5.自定义类型 会调用它自身的构建函数/析构函数
class Stack
{
~Stack()
if(_a)
{
free(_a);
_a = nullptr;
_size = _capacity = 0;
}
private:
int * _a;
int _size;
int _capacity;
};
1.11 拷贝构造 :采用同类对象来构造新的对象
注意:使用传值的方式来实现拷贝构造函数会导致无限递归。在创建对象时,会调用一次拷贝构造函数。
因此,应该采用传引用的方式来实现拷贝构造函数。
疑问:如果传的是引用,那 d1 和 d2 不是同一块空间吗?
传递引用:d1 作为引用传递给拷贝构造函数,这只是为了访问 d1 的成员,而不是共享内存。
创建副本:拷贝构造函数会创建一个新的对象 d2,并将 d1 的成员值复制到 d2 中。因此,d2 和 d1 是两个不同的对象,存在于不同的内存地址。
在创建对象时,会为 d2 分配一个新的对象空间(深拷贝),而传引用不会再次拷贝。
**总结:**使用传值的方式来实现拷贝构造函数,在创建对象时存在一个调用拷贝构造函数(产生新空间d2),在传参时还有创建一个临时对象tmp,这样起码会有二次深拷贝。
而采用采用传引用的方式来实现拷贝构造函数。只会在创建对象时存在一个调用拷贝构造函数(产生新空间d2),在传参时不在创建临时对象tmp,这样起码就不会有第二次深拷贝。
class Data
{
Data(Date d)//存在递归拷贝的问题
{
_year =d._year;
_month = d._month;
_day = d._day;
}
private:
int _year;
int _month;
int _day;
};
Data d2(d1);//或者Data d2=d1;二者等效
关于构造函数Data(Date d)//存在递归拷贝的问题分析:
1.对象初始化时会地调用构造函数,调用之前要传参即将d1传给Data(Date d)中的参数d,由于这个是通过传值的方式传参,会创建一个临时Date tmp=d,会再次调用构造函数,调用之前要传参即将tmp传给Data(Date d),往复调用,无限递归。
无法理解记住即可

1.12 运算符重载
作用:让自定义类型可以向内存类型一样使用运算符 + == += -=等等
class Data
{
bool operator==(const Data& d)//第一个参数是隐藏的,是this指针
{
return this->_year==d._year && this->_month==d._month && this->_day==d._day;
}
Date(int year,int month,int day)//兼容Data d1(2020,4,6);
{
_year = year;
_month =month;
_day = day;
}
private:
int _year;
int _month;
int _day;
};
Data d1(2024,4,9);
Data d2(2024,5,6);
d2-d1;//需要自己定义
d2 == d1;//会被编译器编译为 operator==(&d2,d1);第一个参数是this指针,也就是&d2
d1 > d2;
如何实现连续操作符呢 d3=d2=d1
赋值运算先计算最右边,先计算,d2=d1返回需要也是一个对象,这样 (d3==对象)才能相比
********代码在类中*************
Data& operator=(const Data& d)
{
if(this != &d)
{
_year = d._year;
_month = d._month;
_day = d._day;
}
return *this;
}
1.13 const如何修饰this指针
class Data
{
void print() const//放在外面修饰里面的this指针
{
cout<<_year<<"_"<<_month<<"_"<<_day<<endl;
}
private:
int _year;
int _month;
int _day;
};
1.14 关于类中const权限无法放大的应用
结论:const成员函数内 不能 调用其他非const成员函数
非const成员函数内 可以 调用其他const成员函数
<<<<<<<<<<<<<这些代码在类中>>>>>>>>>>>>>>>>>>>>>>>
void f1() //void f1(Data* this)
{
f2();
//this->f2(this) 权限减小 这里相当于将权限大this传值给下面f2中的权限小的const对象的this
}
void f2() const//void f2(const Data* this)
{}
void f3() const //void f1(const Data* this)
{
f4(); //this->f2(const this) 权限缩小
}
void f4() //void f2(Data* this)
{}
<<<<<<<<<<<<<<<<<<<<<<>>>>>>>>>>>>>>>>>>>>>>>>>>>>
int main()
{
f1();//权限大的调用权限小的const,权限缩小 可以
f3();//保存 权限小的const调用权限大的,权限放大,不可以
return 0;
}
1.15 初始化列表 与 成员变量的声明和定义
1.类中的 引用变量成员 const成员 自定义成员(该类有可以不用传参就可以调用的构造函数)必须放在初始化类表中进行初始化。
2.成员变量的初始化顺序由声明顺序相关,而于初始化列表的顺序无关。
class Date
{
public:
Date(int year,int month,int day)
:_year(year);
,_month(month)
,_day(day)
{
}
}
why?这三种变量必须放在初始化列表中呢?
class B
{
public:
B(int a,int ref)//构造函数时,会定义这些成员变量并初始化。因为引用,const变量和自定义函数(没有默认构造函数,它不会初始化) 必须在定义是赋一个初始值。
//默认构造函数指不需要传参的构造函数
>>>>>>>>这里是成员变量定义的地方>>>>>>>>>>>>>>>>>>>>
:_aobj(a)
,ref(ref)
,_n(10)
{
}
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
private:
>>>>>>>>这里是成员变量声明的地方>>>>>>>>>>>>>>>>>>>>
A _aobj;
int& _ref;
const int _n;
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
}
1.16 类中的 static成员变量和static成员函数
static和普通的成员函数和成员变量的区别:
| 类型 | 存储位置 | this指针 | 访问方式 | 说明 | 示例 |
|---|---|---|---|---|---|
| 静态成员变量 | 静态区 | —— | 可通过类名或对象访问 | 不属于任何特定对象,都存在静态区中,所有对象共享同一份数据。 | Date::currentYear |
| 静态成员函数 | 静态区 | 无 | 通常通过类名访问,也可通过对象访问(不推荐) | 不依赖于具体对象,所以没有this指针,不能访问非静态成员。 | Date::getCurrentDate() |
| 成员变量 | 对象中 | —— | 只能通过对象访问 | 每个对象都有自己的一份副本。 | Date date1; date1.day = 10; |
| 成员函数 | 公共区 | 有 | 只能通过对象访问 | this 指针指向调用该函数的具体对象。 | date1.printDate(); |
总结和部分知识点:
1.只有成员函数有this指针,因为只有它是存储在对象中的,(this指针是指向自己所在的对象空间中对象的地址)。
2.成员函数和成员变量只能通过对象来访问
3.静态的成员函数和成员变量 可以通过对象(很少用)或类域来访问。
4.静态成员函数因为没有this指针,无法访问非静态成员变量。
5.静态成员变量定义必须在类外必须进行。其在类中只能声明,无法定义。
6.非静态成员变量:在构造函数中定义,在类中的private来声明。
7.类中成员变量没有定义只有什么,是在创建对象时,自动调用构建函数时对成员变量进行定义的。
补充:C++中静态成员变量必须在类外进行定义,主要原因:非静态成员变量放在对象中,而静态成员变量放在静态区中,放在外面定义以确保全局范围内只有一个唯一存储空间。
在C++中,静态成员变量必须在类外进行定义的原因与C++的链接性和内存管理有关。
| 关键点 | 说明 |
|---|---|
| 链接性 | 静态成员变量在类定义中声明时,它属于类的接口部分,但不分配内存。它不是特定于某个对象的,而是所有对象共享的,因此必须在类外定义以确保只分配一次内存。 |
| 内存分配 | 静态成员变量在全局数据区分配内存,而不是在每个对象的内存块中分配。这意味着即使创建多个对象,静态成员变量也只有一个实例。 |
| 初始化时机 | 静态成员变量的初始化在 main 函数执行之前完成,即在程序启动阶段,确保在任何对象创建之前已经初始化并可以使用。 |
| 访问控制 | 静态成员变量可以在类外直接通过类名访问,而不需要创建类的实例。这要求它们必须在类外有一个定义,以便编译器生成访问代码。 |
| 多重定义问题 | 如果在类内定义静态成员变量,每次创建对象时都可能尝试定义该变量,导致链接错误,因为会有多个定义分配相同的内存空间。 |
| 编译单元 | C++ 程序通常由多个编译单元组成,静态成员变量在类外定义确保它们在所有编译单元中唯一,避免重复定义的问题。 |
class Date {
public:
static int currentYear; // 静态成员变量
int day; // 成员变量
static void getCurrentDate() { // 静态成员函数
<<<<<<无法访问非静态成员>>>>>>>>>
}
void printDate() { // 成员函数
std::cout << "Day: " << day << ", Year: " << currentYear << std::endl;
}
};
>>>>>>>>初始化静态成员变量在类外必须进行初始化和定义>>>>>>>>>>>>>>>>>
int Date::currentYear = 2024;
// 使用示例
int main() {
Date date1;
date1.day = 10; // 设置成员变量
date1.printDate(); // 调用成员函数
Date::getCurrentDate(); // 调用静态成员函数
return 0;
}
拓展问题:
1.静态成员函数可以调用非静态成员函数吗?不行 无 -> 有 无 无法 生有(×)
静态成员函数 无thsi指针, 非静态成员函数 有this指针,
有this指针才能调用非静态成员函数,如果有this指针,编译器会自动将this指针作为第一个参数传给非静态成员函数。
class Data
{
void fmon(int month) //void print(Data* this,int month)
{
_month = month;//this->_month = month;
}
void fyear(int year)//fun1(Data* this,int year)
{
_year=year; //this->_year=year;
fmon(5); //print(this,5)
}
private:
int _year;
int _month;
int _day;
};
Data d1;
d1.fyear(2024)// d1.fyear(&d1,2014) this接收到来自&d1的值(对象地址)
2.静态成员函数可以调用非静态成员函数吗?行
静态成员函数 无thsi指针, 非静态成员函数 有this指针,
1.18 数组对象 Data a[10]; 会调用10次构造函数
这个数组或者说这块连续的空间,会创建10个Data类型的对象,会调用10次构造函数。
1.19 类中声明时给缺省
class Data
{
public:
Data()
{ }
void Print()
{
cout<<_year<"-"<<_month<<"-"<<_day<<endl;
}
private:
//类中变量不是定义,只是声明。定义是在创建对象时,通过自动调用构建定义生成的。
>>>>>>声明时给缺省值,如果你没有初始时给值,就用缺省值>>>>>>>>>>>>>>>>>>
>>>>>>注意:静态成员变量声明时不可以给值,它需要在类外单独赋值>>>>>>>>>>>>>>>>>>
int _year =0;
int _month = 0;
int _day = 1;
};
1.20 有元函数
作用:在类外去访问类中的私有(private)和保护(protect)的成员变量
1.使用方法:先在类中声明,再在类外定义
2.有元函数可以访问类中私有和保护成员,但不是类的成员函数。
3.有元函数无this指针。
4.一个函数可以是多个类的有元函数。
class Data
{
friend void f(Data& f);//先在类中声明
public:
Data()
{ }
void Print()
{
cout<<_year<"-"<<_month<<"-"<<_day<<endl;
}
private:
int _year =0;
int _month = 0;
int _day = 1;
};
void f(Data& d)
{
d._year = 10;
cout<<d._year<<endl;
}
有元函数的应用场景,普通的类函数也是在公共区,为什么还有搞一个有元函数呢?
举例
如何<<实现重载呢?,如果 operator<<定义在类中
cout<<d1;//编译器的编译为:operator<<(&cout,d1)
此时第一个参数不是&d1,不是this指针,
需要d1<<cout; //编译器的编译为:operator<<(&d1,cout)
但是此种方式和我们的用法习惯区别太大,有没有其他办法呢?
采用第一个参数不是this指针,而有可以使用类中成员变量的函数:有元函数
class Data
{
friend void operator<<(OStream & out);//先在类中声明
public:
Data()
{ }
void Print()
{
cout<<_year<"-"<<_month<<"-"<<_day<<endl;
}
private:
int _year =0;
int _month = 0;
int _day = 1;
};
ostream& operator<<(ostream& out,const Data& d)
{
out<<d._year<<"/"<<d._month<<"/"<<d._day<<endl;
}
补充:
cin 数据类型为:isteam
cout 数据类型为osteam
1.21 有元类
应用场景:在类中想用其他类的私有和保护成员变量
class Time
{
>>>>>>先声明>>>>>>>>>>>之后Data类就有使用Time中的私有和保护的成员变量了
friend class Data;
public:
.......
private:
int _hour;
int _minute;
int _second;
};
class Data
{
void SetTimeOfData(int hour,int monute,int second)
{
_t._hour=hour;
_t.minute = minute;
_t.second = second;
}
private:
int _year;
int _month;
int _day;
Time _t;
};
1.22 内存基础知识

计算机的内存地址和实际硬盘的地址是一一映射的关系
32位计算机 地址为32位,支持最大空间位2^32字节=4G空间
而硬盘有时候不是4G,而是2G呢?课件硬盘是通过挂载的方式,将物理地址和计算机的虚拟4G地址一一来映射的。
1.23 C++的动态内存(堆上空间)管理 new delete
c语言的malloc 申请空间
/calloc 申请空间+初始化
/realloc 对已有的空间进行扩容
/free 不做解释
C++的内存管理方式:new 和delete
int* ptr4 = new int; 申请一个int类型空间
int* ptr5 = new int(10);申请1个int类型空间,并初始化为10
int* ptr6 = new int[3] ; 申请数组空间,里面有3个int类型
delete ptr4;
delete ptr5;
delete[] ptr6; 数据空间的删除
new delete和malloc free的区别
1.对于内置类型,他们的效果是一样的
2.对于自定义类型(类),c++ 中的new可以申请空间,在申请成功后,会自动调用构造函数进行初始化,delete可以释放空间,同时自动调用析构函数
| 特性 | new/delete (C++) | malloc/free (C ) |
|---|---|---|
| 内存分配 | new申请空间并调用构造函数 | malloc仅申请空间,不初始化 |
| 内存释放 | delete释放内存并调用析构函数 | free仅释放内存,不进行清理 |
| 类型安全 | 类型安全,自动转换指针类型 | 不是类型安全的,需要手动类型转换 |
| 返回类型 | 对应类型的指针 | void* |
| 异常处理 | 处理内存分配失败时抛出异常 | 不抛出异常,返回NULL |
| 重载 | 可以重载全局和类的new/delete | 不能重载,全局可用 |
1.24 operator new(不调用构造)和new(调用构造) operator delete(不调用析构) 和delete(调用析构)
malloc 失败返回NULL
operator new >>>> maloc+失败抛出异常
new 1.自动调用构造函数,失败抛出异常
A* p1 = (A*)malloc(sizeof(A));
A* p1 = (A*)operator new(sizeof(A));
size_t size=2;
void* p4 = malloc(size*1024*1024*1204);
cout<<p4<<endl;失败返回0.也就是NULL
void*p5 = operator new(size*1024*1024*1204);
cout<< p5 <<endl;失败抛异常
1.25 A=B的返回值是A
1.26 定位new
场景:对已存在的一块空间上调用构造函数来初始化
语法:new(空间指针)类名(参数);
int mian()
{
A*p1 = new A;
A* p2 = (A*)operator new(sizeof(A));
new(p2)A(10);//手动调用构造
p2->~A();//手动定义析构
operator delete(p2);
}
1.27 模版template 兼容任何类型的代码 函数模版
void Swap(int& a,int& b)
{
int temp = a;
a = b;
b = temp;
}
void Swap(double& a,double& b)
{
double temp = a;
a = b;
b = temp;
}
void Swap(char& a,char& b)
{
char temp = a;
a = b;
b = temp;
}
代码重复过高,有没有采用一套代码兼容不同的数据类型呢?采用模版编程
template<class T>
void Swap(T& x1,T& x2)
{
T x = x1;
x1 = x2;
x2 = x;
}
int main()
{
int a = 0 ,b = 1;
Swap(a, b);
double c=1.11, d = 2.22;
Swap(c, d);
return 0;
}
模版原理:

1.28 类模版
c语言和c++的面向对象区别

c语言实现的stack
#include <iostream>
#include <cstdio>
typedef int STDateType;
typedef struct Stack_C
{
STDateType *a;
int _size;
int _capacity;
}Stack_C;
void Stack_CInit(Stack_c *ps);
void Stack_CDestory(Stack_c *ps);
void Stack_cpush(Stack_c *ps,STDateType x);
void stack_cPop(Stack_c *ps);
int mian()
{
Stack_C st_c;
Stack_CInit(&st_c);
Stack_Cpush(&st_c,1);
Stack_Cpush(&st_c,2);
Stack_CPop(&st_c);
Stack_CDestory(&st_c);
}
模版+类的实现 stack
#include <iostream>
#include <cstdio>
using namepace std;
template <class T>
class Stack_Cpp
{
public:
Stack_CPP()
{}
~stack_CPP()
{}
void Push(T x);
void Pop();
ptivate:
T* _a;
int _size;
int _capacity;
}
int main()
{
Stack_CPP<int> st_cpp_int;
st_cpp_int.Push(1);
st_cpp_int.push(2.1); 2.1会被强制类型转换为2
st_cpp_int.pop();
Stack_CPP<double> st_cpp_double;
st_cpp_double.Push(1.1);
st_cpp_double.push(2);2会被强制类型转换为2.0
st_cpp_double.pop();
}
1.29 模版底层原理

1.30 匿名对象 对象名();
class Solution
{
void fun(int n)
{
cout<<n<<endl;
retrun n;
}
};
Solution s1; s1的什名周期main函数中,mian函数结束时,才会调用析构函数
s1.fun(10);
Solution() 匿名对象,生命周期就在这一行,出了这一行自动调用析构函数
Solution().fun(10);

被折叠的 条评论
为什么被折叠?



