命名空间 std
是C++的标准命名空间,它是一个定义在 C++ 标准库中的所有类、函数和变量的命名空间。使用方法如下:
1 std::cout << "Hello" << std::endl;
自定义命名空间:
1 2 3 4 5 6 7 namespace cir { constexpr double PI = 3.145926 ; double get_L (double R) ; double get_S (double R) ; }
其中在 C++ 中,如果你想在命名空间内定义一个常量(如 PI
),通常需要使用 const
关键字或者将其定义为 constexpr
(C++11 及以上版本)。直接使用 double PI = 3.14;
在命名空间中是不合法的,因为命名空间不支持直接初始化变量。你需要使用 const
或 constexpr
。
接下载需要具体化函数内容有两种写法如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 #include "cir.h" double cir::get_L (double R) { return R*2 *cir::PI; } double cir::get_S (double R) { return R*R*cir::PI; } namespace cir { double get_L (double R) { return R*2 *cir::PI; } double get_S (double R) { return R*R*cir::PI; } }
std包含的内容
std
命名空间包含了许多类、函数和对象,例如:
输入输出库(如std::cout , std::cin , std::endl
)
容器类(如std::vector , std::map , std::set
)
字符串类(std::string
)
异常类(std::exception
和相关子类)
算法(如std::sort , std::find
)
实用工具(如std::pair , std::tuple
)
其他许多功能
使用建议
对于小型代码或示例代码,使用using namespace std;
通常是安全的。对于大型项目或库,建议显式地使用std::
前缀,以避免潜在的名称冲突,并提高代码的可读性和可维护性。std
命名空间是 C++ 编程的基础部分,理解和正确使用它对于编写健壮和高效的 C++ 代码至关重要。
输入输出 C++ 中的输入和输出(I/O)主要是通过标准库中的输入输出流来实现的。最常用的是iostream
库,它
提供了用于输入和输出的基本流类,包括cin
、cout
、cerr
和clog
。
基本使用输出流如下:
1 std::cout << "Hello" << "woeld" << i << std::endl;
输入(箭头指向数据的方向):
标准错误流 ( cerr
) 和标准日志流 ( clog
)
cerr
用于输出错误消息。与cout
不同,cerr
不是缓冲的,这意味着它会立即输出。
clog
类似于cerr
,但它是缓冲的。它通常用于记录错误和日志信息。
变量类型 C++中可以直接使用bool
类型的数据,包含true
,false
值。
内联函数 内联函数(Inline Function)是C++中一种特殊的函数,其定义直接在每个调用点展开。这意味着编译器会将函数调用替换 为函数本身的代码,这样可以减少函数调用的开销,尤其是在小型函数中。主要作用为提升代码的可读性。关键字 inline
必须与函数定义体放在一起才能使函数成为内联 。在函数声明处添加 inline
关键字虽然没有错,但这种做法是无效的,编译器会忽略函数声明处的 inline
关键字。
1 2 3 inline int add (int i, int j) { return i+j; }
Lambda匿名函数 Lambda 表达式是 C++11 引入的一种匿名函数的方式,它允许你在需要函数的地方内联地定义函数,而无需单独命名函数。 相较于普通非匿名函数,匿名函数无需进行另外的声明和定义,仅当调用该匿名时,函数体才会创建,且调用完毕后会立即释放资源。因此匿名函数会更加节省空间,常用于像std::sort
这样可以重写排序方式的函数。Lambda表达式基本语法如下:
1 2 3 4 5 6 [capture clause](parameters) -> return_type{ return expression; }
Lambda 表达式由以下部分组成:
捕获列表(Capture clause :用于捕获外部变量,在 Lambda 表达式中可以访问这些变量。捕获列表可以为空,也可以包含变量列表[var1, var2, ...]
。
参数列表(Parameters) :与普通函数的参数列表类似,可以为空或包含参数列表(param1,param2, ...)
。
返回类型(Return type) :Lambda表达式可以自动推断返回类型auto,也可以显式指定返回类型 -> return_type 。如果函数体只有一条返回语句,可以省略返回类型。
函数体(Body) :Lambda 表达式的函数体,包含需要执行的代码。
匿名函数的使用例子:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 auto testReturn = [](int a1, int a2) {return a1>a2 };bool flag = testReturn (23 , 21 );cout<<flag<<endl; int as = 100 ;auto testReturn = [](int a1, int a2) {return a1>a2 };bool flag = testReturn (as, 21 );cout<<flag<<endl; int as = 100 ;auto testReturn = [&](int a1, int a2) {a1 = 10 ; return a1>a2 };bool flag = testReturn (as, 21 );cout<<flag<<" " <<as<<endl;
重点: 区分auto add = [=](int a1, int a2) {return a1+a2 };
和auto add = [&](int a1, int a2) {return a1+a2 }
。其中的区别主要为[=]
和[&]
,其中[=]
表示按数值 传入上方所用的变量,其中[&]
表示按引用 传入上方所用的变量。按数值 传入的变量只可以访问不能修改,按引用 传入的变量可以访问并且修改。
Lambda还有一个重要的作用就是把自身当作回调函数的参数 ,演示代码如下:
1 2 3 4 5 6 7 8 9 10 int get_best (int a, int b, bool (*compare)(int a, int b)) { if (compare (a, b))return a; else return b; } int main (void ) { std::cout << get_best (12 , 34 , [](int a,int b)->bool {if (a<b)return true ; else return false ;}) << std::endl; return 0 ; }
使用该方法可以快速的编写回调函数。
类 类的概念是面向对象编程的核心之一,其主要目的是将数据和与数据相关的操作 封装在一起。
C++ 类的基本结构通常包含:
数据成员(Attributes) :定义类的属性。这些是类内部的变量,用于存储对象的状态。
成员函数(Methods) :定义类的行为。这些是可以操作对象的数据成员的函数。
构造函数和析构函数 :特殊的成员函数。构造函数在创建对象时自动调用,用于初始化对象。析构函数在对象销毁时调用,用于执行清理操作。
访问修饰符 :如public , private , protected
用于控制对类成员的访问权限。例如,public
成员可以在类的外部访问,而private
成员只能在类内部访问。
继承 :允许一个类继承另一个类的特性。这是代码重用和多态性的关键。通过这些特性,C++ 类提供了一种强大的方式来组织和处理数据,使得代码更加模块化、易于理解和维护。
类的使用示例代码如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 class car {public : std::string color; std::string brand; std::string type; int year; void (*PrintCarInfo)(std::string color, std::string brand, std::string type, int year); }; void BWM (std::string color, std::string brand, std::string type, int year) { std::string str = "color:" + color + " brand:" + brand + " type:" + type + " year:" + std::to_string (year); std::cout << str << std::endl; } void AOD (std::string color, std::string brand, std::string type, int year) { std::string str = "color:" + color + " brand:" + brand + " type:" + type + " year:" + std::to_string (year); std::cout << str << std::endl; } int main (void ) { car a1; a1. type = "A1" ; a1. brand = "BWM" ; a1. color = "RED" ; a1. year = 2020 ; a1. PrintCarInfo = BWM; a1. PrintCarInfo (a1. color, a1. brand, a1. type, a1. year); car *Q7; Q7 = new car (); Q7->type = "Q7" ; Q7->brand = "AOD" ; Q7->color = "BLACK" ; Q7->year = 2018 ; Q7->PrintCarInfo = AOD; Q7->PrintCarInfo (Q7->color, Q7->brand, Q7->type, Q7->year); return 0 ; }
以上代码使用函数指针的方式传递函数,实际上还是C语言的方式。以下将展示C++类当中如何定义成员函数。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 class car {public : std::string color; std::string brand; std::string type; int year; void (*PrintCarInfo)(std::string color, std::string brand, std::string type, int year); void RealPrintCarInfo1 () { std::string str = "color:" + color + " brand:" + brand + " type:" + type + " year:" + std::to_string (year); std::cout << str << std::endl; } void RealPrintCarInfo2 () ; }; void car::RealPrintCarInfo2 () { std::string str = "color:" + color + " brand:" + brand + " type:" + type + " year:" + std::to_string (year); std::cout << str << std::endl; }
当然一个类可以包含一个类。在 C++中,一个类包含另一个类的对象称为组合(Composition)。这是一种常见的设计模式,用于表示一个类是由另一个类的对象组成的。这种关系通常表示一种”拥有”(”has-a”)的关系。
普通变量访问成员变量或者成员函数,使用 “.
” 运算符
指针变量访问成员变量或者成员函数,使用“->
”运算符,像C语言的结构体用法
示例代码如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 #include <stdio.h> #include <stdlib.h> #include <string> #include <iostream> using namespace std;class Wheel { public : string brand; int year; void wheelPrintInfo () ; }; void Wheel::wheelPrintInfo () { cout << "我的轮胎品牌是:" << brand << endl; cout << "我的轮胎日期是:" << year << endl; } class Car { public : string color; string brand; string type; int year; Wheel wl; Wheel *pwl; void (*printCarInfo)(string color,string brand,string type, int year); 指针,指向车介绍函数 void (*carRun)(string type); void (*carStop)(string type); void realPrintCarInfo () ; }; void Car::realPrintCarInfo () { string str = "车的品牌是:" + brand + ",型号是: " + type + ",颜色是:" + color + ",上市年限是:" + std::to_string (year); cout << str << endl; } void bwmThreePrintCarInfo (string color,string brand,string type, int year) { string str = "车的品牌是:" + brand + ",型号是: " + type + ",颜色是:" + color + ",上市年限是:" + std::to_string (year); cout << str << endl; } void A6PrintCarInfo (string color,string brand,string type, int year) { string str = "车的品牌是:" + brand + ",型号是: " + type + ",颜色是:" + color + ",上市年限是:" + std::to_string (year); cout << str << endl; } int main () { Car BWMthree; BWMthree.color = "白色" ; BWMthree.brand = "宝马" ; BWMthree.type = "3系" ; BWMthree.year = 2023 ; BWMthree.pwl = new Wheel (); BWMthree.pwl->brand = "米其林" ; BWMthree.pwl->year = 2023 ; BWMthree.printCarInfo = bwmThreePrintCarInfo; BWMthree.printCarInfo (BWMthree.color,BWMthree.brand,BWMthree.type,BWMthree.year); BWMthree.realPrintCarInfo (); Car *AodiA6 = new Car (); AodiA6->color = "黑色" ; AodiA6->brand = "奥迪" ; AodiA6->type = "A6" ; AodiA6->year = 2008 ; AodiA6->printCarInfo = A6PrintCarInfo; AodiA6->pwl = new Wheel; AodiA6->pwl->brand = "普利司通" ; AodiA6->pwl->year = 2012 ; AodiA6->printCarInfo (AodiA6->color,AodiA6->brand,AodiA6->type,AodiA6->year); AodiA6->realPrintCarInfo (); AodiA6->pwl->wheelPrintInfo (); return 0 ; }
权限 C++中的访问权限主要分为三种:public
、private
和protected
。这些权限决定了类成员(包括数
据成员和成员函数)的可访问性。以下是一个总结表格,说明了在不同情况下这些权限如何应用:
访问权限
类内部
同一个类的对象
派生类
类外部
public
✅
✅
✅
✅
private
✅
❌
❌
❌
protected
✅
❌
✅
❌
使用权限(如public
、private
和protected
)在C++中是一种关键的封装手段,它们旨在控制对类成员的访问。下面是一个表格,总结了使用权限的主要好处和潜在缺点:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 #include <iostream> #include <string> using namespace std;class BankAccount {private : string name; string addr; int age; double balance; public : string bankAddr; void registerMes (string newName, string newAddr,int newAge,double newBalance) ; void withdraw (double amount) ; void deposit (double amount) ; double getBalance () ; void printUserInfo () ; }; void BankAccount::printUserInfo () { string mesTem = "账户名:" + name + ",地址:" + addr + ",年龄:" + std::to_string (age) + ",存款:" + std::to_string (balance); cout << mesTem << endl; } void BankAccount::registerMes (string newName, string newAddr,int newAge,double newBalance) { name = newName; addr = newAddr; age = newAge; balance = newBalance; } void BankAccount::deposit (double amount) { if (amount > 0 ) { balance += amount; } else { cerr << "Deposit amount must be positive." << endl; } } void BankAccount::withdraw (double amount) { if (amount > balance) { cerr << "Insufficient funds." << endl; } else if (amount <= 0 ) { cerr << "Withdrawal amount must be positive." << endl; } else { balance -= amount; } } double BankAccount::getBalance () {return balance;} int main () { BankAccount user1; user1. registerMes ("老陈" ,"深圳光明区" ,35 ,100 ); user1. printUserInfo (); user1. deposit (1000 ); cout << user1. getBalance () << endl; user1. withdraw (30 ); cout << user1. getBalance () << endl; return 0 ; }
引用 引用变量是一个别名,也就是说,它是某个已存在变量的另一个名字。一旦把引用初始化为某个变量,就可以使用该引用名称或变量名称来指向变量。在C语言中,一个数据对应一个内存,通过由一个变量名来访问这个内存空间的数据,叫做直接访问,相对直接访问,有个间接访问的说法,叫做指针。而引用相当于又给这个内存中的数据提供了一个新的变量名,这个变量名功能比传统变量名更特殊,是直达地址的,后续代码验证!
以下代码通过使用引用变量作为参数,直接体现其直达地址的特性。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 #include <iostream> using namespace std;void swap (int & x, int & y) { int temp; temp = x; x = y; y = temp; return ; } int main () { int a = 100 ; int b = 200 ; cout << "交换前,a 的值:" << a << endl; cout << "交换前,b 的值:" << b << endl; swap (a, b); cout << "交换后,a 的值:" << a << endl; cout << "交换后,b 的值:" << b << endl; return 0 ; }
通过使用引用来替代指针 ,会使 C++ 程序更容易阅读和维护。C++ 函数可以返回一个引用,方式与返回一个指针类似。当函数返回一个引用时,则返回一个指向返回值的隐式指针。这样,函数就可以放在赋值语句的左边。 例如,请看下面这个简单的程序:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 #include <iostream> using namespace std;double vals[] = {10.1 , 12.6 , 33.1 , 24.1 , 50.0 };double & setValues (int i) { double & ref = vals[i]; return ref; } int main () { cout << "改变前的值" << endl; for ( int i = 0 ; i < 5 ; i++ ) { cout << "vals[" << i << "] = " ; cout << vals[i] << endl; } setValues (1 ) = 20.23 ; setValues (3 ) = 70.8 ; cout << "改变后的值" << endl; for ( int i = 0 ; i < 5 ; i++ ) { cout << "vals[" << i << "] = " ; cout << vals[i] << endl; } return 0 ; }
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 #include <iostream> using namespace std;int & swap (int * point, int num) { int & ref = point[num]; return ref; } int main () { int x[5 ] = {1 ,2 ,3 ,4 ,5 }; swap (x, 0 ) = 12 ; cout << x[0 ] << " " << x[1 ] << endl; return 0 ; }
重载 函数重载 在同一个作用域内,可以声明几个功能类似的同名函数 ,这些同名函数的形式参数(指参数的个数、类型或者顺序)必须不同。您不能仅通过返回类型的不同来重载函数。下面的实例中,同名函数 print()
被用于输出不同的数据类型:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 #include <iostream> using namespace std;class show_data { public : void print (int a) { cout << "int " << a << endl; } void print (char a) { cout << "char " << a << endl; } void print (char str[]) { cout << "string " << str << endl; } }; int main () { show_data p; p.print (10086 ); p.print ("hello world" ); p.print ('a' ); return 0 ; }
运算符重载 在C++中,运算符重载是一个允许程序员自定义各种运算符(如 + , - , == , != 等)在自定义类型(类或结构体)上的行为的特性。这意味着你可以定义类似于内置类型的运算符行为,使你的自定义类型更加直观和易于使用。
基本原则
不可以创建新的运算符 :只能重载已经存在的运算符。
至少有一个操作数是用户定义的类型 :不能重载两个基本类型的运算符。
不能更改运算符的优先级 :重载的运算符保持其原有的优先级和结合性。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 #include <iostream> using namespace std;class point { public : int x, y; point operator +(point ptmp)const ; }; point point::operator +(point ptmp)const { point ref; ref.x = x+ptmp.x; ref.y = y+ptmp.y; return ref; } int main () { point p1,p2; p1. x = 12 ; p1. y = 3 ; p2. x = 34 ; p2. y = 9 ; point p3 = p1 + p2; cout << p3. x << " " << p3. y <<endl; return 0 ; }
其中重载运算符需要使用operator
关键字。后面添加const
关键字可以保证被运算变量为常量,在计算过程中不被改变。
构造函数 类的构造函数是类的一种特殊的成员函数 ,它会在每次创建类的新对象时执行。构造的是构造成员变量的初始化值,内存空间等 构造函数的名称与类的名称是完全相同的,并且不会返回任何类型,也不会返回 void 。构造函数可用于为某些成员变量设置初始值 。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 #include <iostream> using namespace std;class car { private : string brand; int year; public : car () { cout << "Class Init Success" <<endl; brand = "BWM" ; year = 2021 ; cout << brand << year << endl; } }; int main () { car* p1; p1 = new car (); return 0 ; }
默认的构造函数没有任何参数,但如果需要,构造函数也可以带有参数 。这样在创建对象时就会给对象赋初始值,如下面的例子所示:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 #include <iostream> using namespace std;class car { private : string brand; int year; public : car () { cout << "Class Init Success" <<endl; brand = "BWM" ; year = 2021 ; cout << brand << year << endl; } car (string B, int Y) { cout << "Class Init Success" <<endl; brand = B; year = Y; cout << brand << year << endl; } }; int main () { car* p1; p1 = new car (); car p2 ("ODE" , 2024 ) ; car* p3; return 0 ; }
在C++中,使用初始化列表 来初始化类的字段是一种高效的初始化方式,尤其在构造函数中。初始化列表直接在对象的构造过程中初始化成员变量 ,而不是先创建成员变量后再赋值。这对于提高性能 尤其重要,特别是在涉及到复杂对象或引用和常量成员的情况下。初始化列表紧跟在构造函数参数列表后面,以冒号(:
)开始,后跟一个或多个初始化表达式,每个表达式通常用逗号分隔。下面是使用初始化列表初始化字段的例子:
1 2 3 4 5 6 7 8 9 10 11 class MyClass { private : int a; double b; std::string c; public : MyClass (int x, double y, const std::string& z) : a (x), b (y), c (z) { } };
在这个例子中,MyClass
有三个成员变量:a
( int 类型)、b
( double 类型)和c
(std::string
类型)。当创建MyClass
的一个实例时,我们通过构造函数传递三个参数,这些参数被用于通过初始化列表直接初始化成员变量。初始化列表: a(x), b(y), c(z)
的意思是用x
初始化a
,用y
初始化b
,用z
初始化c
。初始化列表的优点包括:
效率 :对于非基本类型的对象,使用初始化列表比在构造函数体内赋值更高效,因为它避免了先默认构造然后再赋值的额外开销。
必要性 :对于引用类型和常量类型的成员变量,必须使用初始化列表,因为这些类型的成员变量在构造函数体内不能被赋值。
顺序 :成员变量的初始化顺序是按照它们在类中声明的顺序,而不是初始化列表中的顺序。使用初始化列表是C++中推荐的初始化类成员变量的方式,因为它提供了更好的性能和灵活性。
使用示例如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 #include <iostream> using namespace std;class car { private : string brand; int year; public : car (string B):brand (B),year (2021 ){ cout << "Class Init Success" <<endl; cout << brand << year << endl; } }; int main () { car* p3; p3 = new car ("Li" ); return 0 ; }
析构函数 析构函数是C++中的一个特殊的成员函数,它在对象生命周期结束时被自动调用,用于执行对象销毁前的清理工作。析构函数特别重要,尤其是在涉及动态分配的资源(如内存、文件句柄、网络连接等)的情况下。
基本特性
名称 :析构函数的名称由波浪号(~
)后跟类名构成,如~MyClass()
。
无返回值和参数 :析构函数不接受任何参数,也不返回任何值。
自动调用 :当对象的生命周期结束时(例如,一个局部对象的作用域结束,或者使用delete
删除一个动态分配的对象),析构函数会被自动调用。
不可重载 :每个类只能有一个析构函数。
继承和多态 :如果一个类是多态基类,其析构函数应该是虚的。
代码示例如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 #include <iostream> using namespace std;class my_class { private : int * Data; public : my_class (int size){ Data = new int [size]; } ~my_class (){ cout << "Function has been used" << endl; delete [] Data; } }; int main () { my_class p1 (12 ) ; return 0 ; }
关键字 this关键字 在 C++ 中,this
关键字是一个指向调用对象的指针 。它在成员函数内部使用,用于引用调用该函数的对象。使用this
可以明确指出成员函数正在操作的是哪个对象的数据成员。下面是一个使用Car
类来展示this
关键字用法的示例:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 #include <iostream> using namespace std;class car { private : string brand; string model; int year; public : car (string A, string B, int C) { this ->brand = A; this ->model = B; this ->year = C; } void display () ; }; void car::display () { cout << brand << model << year << endl; } int main () { car p4 ("Tsla " , "Modle Y " , 2013 ) ; p4. display (); return 0 ; }
通过this
指针可以实现链式调用 操作。链式调用是一种编程风格,允许对象连续 调用多个方法,每个方法都返回对象自身(this
指针),从而可以继续调用下一个方法。这在C++中通常用在类设计时,特别是在构建者模式(Builder Pattern)和流式API设计中。以下是一个链式调用的示例:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 #include <iostream> using namespace std;class car { private : string brand; string model; int year; public : car () { cout << "Class Init Success" <<endl; brand = "BWM" ; year = 2021 ; cout << brand << year << endl; } void display () ; car& setBrand (const std::string& b) { brand = b; return *this ; } car& setModel (const std::string& m) { model = m; return *this ; } car& setYear (int y) ; }; void car::display () { cout << brand << model << year << endl; } car& car::setYear (int y) { year = y; return *this ; } int main () { car p5; p5. setBrand ("NBWM " ).setModel ("X5 " ).setYear (2010 ).display (); return 0 ; }
new关键字 在C++中,new
关键字用于动态分配内存。它是C++中处理动态内存分配的主要工具之一,允许在程序运行时根据需要分配内存。
分配单个对象 :使用new
可以在堆上动态分配一个对象。例如,new int
会分配一个int
类型的空间,并返回一个指向该空间的指针。
分配对象数组 :new
也可以用来分配一个对象数组。例如,new int[10]
会分配一个包含10个整数的数组。
delete关键字 new
与 delete
配对使用
使用new
分配的内存必须显式地通过delete
(对于单个对象)或delete[]
(对于数组)来释放,以避免内存泄露:
释放单个对象:
释放数组:
示例代码
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 class MyClass { public : MyClass () { std::cout << "Object created" << std::endl; } }; int main () { MyClass* myObject = new MyClass (); int * myArray = new int [5 ]{1 , 2 , 3 , 4 , 5 }; delete myObject; delete [] myArray; return 0 ; }
在这个例子中,new
被用来分配一个MyClass
类型的对象和一个整数数组,然后使用delete
和delete[]
来释放内存。每个new
都对应一个delete
,保证了动态分配的内存被适当管理。
静态成员 静态成员变量
定义 :静态成员变量是类的所有对象共享的变量。与普通成员变量相比,无论创建了多少个类的实例,静态成员变量只有一份拷贝 。
初始化 :静态成员变量需要在类外进行初始化,通常在类的实现文件中。
访问 :静态成员变量可以通过类名直接访问,不需要创建类的对象。也可以通过类的对象访问。
用途 :常用于存储类级别的信息(例如,计数类的实例数量)或全局数据需要被类的所有实例共享。
静态成员函数
定义 :静态成员函数是可以不依赖于类的实例而被调用的函数 。它不能访问类的非静态成员变量和非静态成员函数。
访问 :类似于静态成员变量,静态成员函数可以通过类名直接调用 ,也可以通过类的实例 调用。
用途 :常用于实现与具体对象无关的功能,或访问静态成员变量。
使用示例如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 #include <iostream> using namespace std;class my_class { private : int * Data; static int NumOfClass; public : my_class (){ Data = new int [5 ]; NumOfClass++; } ~my_class (){ cout << "Function has been used" << endl; delete [] Data; } static void Cout_Class () { NumOfClass++; cout << NumOfClass << endl; } }; int my_class::NumOfClass = 0 ;int main () { my_class p1[6 ]; my_class::Cout_Class (); my_class::Cout_Class (); my_class::Cout_Class (); my_class::Cout_Class (); return 0 ; }
注意静态变量要在类外面初始化。 静态成员变量在C++中的一个典型应用是用于跟踪类的实例数量。这个案例体现了静态成员变量的特性,它们在类的所有实例之间共享,因此适合于存储所有实例共有的信息。
继承