引用
int a=10;
例如 int& ra=a;
利用引用可以解决数值交换的函数的问题
void abc (int& a,int& b)
{
int tmp;
tmp = a;
a=b;
b=tmp;
}
int main()
{
int a=10;
int b=20;
cout << "交换之前:" << endl ;
cout << " a= " << a << endl;
cout << " b= " << b << endl;
abc(a,b);
cout << "交换之后:" << endl;
cout << " a = " << a << endl;
cout << "b= " << b << endl ;
return 0;
}
传递参数时 采用引用
引用很容易与指针混淆,他们之间有三个主要的不同:
①不存在空引用 ,引用必须连接到一块合法的内存
②一旦引用被初始化为一个对象,就不能被指向另一个对象,指针可以在任何时候被指向到另一个对象。
③引用必须在创建时被初始化,指针可以在任何事件被初始化
④官方没有明确说明,但是引用确实不是传统意义上的独立变量
当返回一个引用时,要注意被引用的对象不能超过作用域,所以返回一个对局部变量的引用是不合法的,但是可以返回一个对静态变量的引用。
重载
①重载相等的运算符
operator==
bool Person::operator==(Person pTmp)
{ return pTmp.name == name && pTmp.age ==age; //检查两个对象的name成员是否相等 检查两个对象的age成员是否相等
}
#include <iostream>
using namespace std;
class Person
{
public:
string name;
int age;
bool operator==(Person pTmp); //重载相等的运算符名称 operator==
};
bool Person::operator==(Person pTmp)
{
return pTmp.name == name && pTmp.age ==age; //检查两个对象的name成员是否相等 检查两个对象的age成员是否相等
}
int main()
{
//假设我们认定名字和年龄一样的两个对象是同一个人
Person p1;
p1.name ="张三";
p1.age =8;
Person p2;
p2.name ="张三";
p2.age= 8;
bool ret = p1==p2; // “==” 直接用于调用函数
cout << ret << endl;
return 0;
}
②重载+的运算符
operator+
Point Point::operator+(Point ptmp)
{
Point ret;
ret.x = x + ptmp.x;
ret.y = y + ptmp.y;
return ret;
}
#include <iostream>
using namespace std;
class Point{
public:
int x,y;
Point operator+(Point ptmp);
};
Point Point::operator+(Point ptmp)
{
Point ret;
ret.x = x + ptmp.x;
ret.y = y + ptmp.y;
return ret;
}
int main()
{
Point p1;
p1.x =2;
p1.y =3;
Point p2;
p2.x= 3;
p2.y =4;
Point p3= p1+p2;
cout << "P3.x=" <<p3.x << endl;
cout << "P3.y=" << p3.y <<endl;
return 0;
}
②重载函数的运算符
下面分别写了无参数的 函数构造 一个参数的函数构造 两个函数的参数构造(调用时 自动识别参数 比配函数 使用指针 或者 不用 都可以)
以及采用初始化列表进行构造
Car(string b,string t,int y):brand(b),type(t),year(y){ //brand(b) 表示brand =b brand type year 的顺序尽量不要错误 不然会警告 但是不影响运行 cout << "参数列表的方式进行构造" << endl;
}
#include <iostream>
using namespace std;
class Car{
public:
string brand;
string type;
int year;
Car(string b,string t,int y):brand(b),type(t),year(y){ //brand(b) 表示brand =b brand type year 的顺序尽量不要错误 不然会警告 但是不影响运行
cout << "参数列表的方式进行构造" << endl;
}
Car(){
cout <<"构造函数被调用!" << endl;
}
Car(string b ,int y){
cout << "带有参数的构造函数被调用" << endl ;
brand =b ;
year =y;
}
Car(string b ){
cout << "带有一个参数的构造函数被调用" << endl ;
brand =b ;
}
void dispaly(){
cout << "Brand: " << brand << ",Year:" << year << endl;
}
void displayAll(){
cout << "Brand: " << brand << ",Year:" << year << ",Type: " << type <<endl;
}
};
int main()
{
Car car;
car.brand ="宝马";
car.year = 2023;
car.dispaly ();
Car *pcar= new Car("捷豹",2025);
pcar->dispaly();
Car car2("比亚迪秦");
car2.year =2025;
car2.dispaly();
Car car3("林肯","航海家",2025);
car3.displayAll();
return 0;
}
在下面的这个例子中,Car类的构造函数使用this 指针来区分成员变量和构造函数参数,同样,setYear成员函数使用this 指针来返回调用该函数的对象的引用,这允许链式调用。
car.setYear(2026).display();
Car(string brand,int year){
this->brand= brand;
this->year =year; }
#include <iostream>
#include <string>
using namespace std;
class Car{
private:
string brand;
int year;
public:
Car(string brand,int year){
this->brand= brand;
this->year =year;
// cout << "构造函数中:" << endl;
// cout << this << endl;
}
void display() {
cout << "Brand: " << this->brand <<",Year: " << this->year << endl;
}
Car& setYear(int year){
this->year=year;
return *this;
}
};
int main()
{
Car car("宝马",2024);
car.display();
//链式调用
car.setYear(2026).display();
// Car car("宝马",2024);
// cout << "main函数中: " << endl ;
// cout << &car << endl;
// Car car2("宝马",2024);
// cout << "main函数中: " << endl ;
// cout << &car2 << endl;
// return 0;
}
new 的关键字
在C++中,new关键字用于动态分配内存。它是C++中处理动态内存分配的主要工具之一,允许程序运行时更具需要分配内存。
分配单个对象:使用new可以在堆上动态分配一个对象。例如,new int 会分配一个int 类型的空间,并返回一个指向空间的指针。
int *ptr = new int;
分配对象数组
int *arr =new int[10];
初始化 :可以在new表达式中使用初始化。对于单个对象,可以使用构造函数的参数
myClass * obj = new MyClass(arg1,arg2);
delete 的关键字
用于释放内存
析构函数
析构函数是C++中的一个特殊的成员函数,他在对象生命周期结束时被自动调用,用于执行对象销毁前的清理工作。析构函数特别重要,尤其是在涉及动态分配的资源(如内存、文件句柄、网络连接等)的情况下
基本特性
1.名称: 析构函数的名称有波浪号(~)后跟类名构成,如~MyClass()
2.无返回值和参数: 析构函数不接受任何参数,也不返回任何值
3.自动调用:当对象的生命周期结束时(例如,一个局部对象的作用域结束,或者使用delete 删除一个动态分配的对象),析构函数会被自动调用
4.不可重载:每个类只能有一个析构函数。
5.继承和多态:如果一个类是多态基类,其析构函数应该是虚的。
#include <iostream>
using namespace std;
class Myclass{
private:
int* datas;
public:
Myclass(int size){
datas =new int[size];
}
~Myclass(){
cout << "析构函数被调用" << endl;
delete[] datas;
}
};
int main()
{
int a;
Myclass m1(5);
Myclass *m2 =new Myclass(10);
cin >> a;
return 0;
}
静态变量
#include <iostream>
using namespace std;
class Test{
public:
void printInfo();
};
class Myclass{
public:
int datas;
static int staticValue;
void printfInfo(){
cout << datas << endl;
}
static int getStaticValue (){
return staticValue ;
}
};
int Myclass::staticValue =0; //静态变量必须在外边
void Test::printInfo()
{
Myclass::staticValue++;
cout << "Test对象打印" << endl;
cout << Myclass:: getStaticValue() << endl ;
}
int main()
{
Test t;
t.printInfo();
cout << Myclass::staticValue << endl;
cout << Myclass::getStaticValue() << endl ;
return 0;
}
/*
使用静态成员变量来跟踪类实例的数量
*/
#include <iostream>
using namespace std;
class Myclass{
public:
static int staticNumodInstance;
Myclass(){
staticNumodInstance++;
} //构造函数 每次创建新对象时自动调用
~Myclass(){
staticNumodInstance--;
}
static int getNumofInstance (){
return staticNumodInstance ;
}
};
int Myclass::staticNumodInstance= 0;
int main()
{
Myclass m1; //会调用Myclass()
cout << Myclass::staticNumodInstance << endl;
Myclass m2;
cout << Myclass::staticNumodInstance << endl;
{
Myclass m3;
cout << Myclass::staticNumodInstance << endl;
Myclass m4;
cout << Myclass::staticNumodInstance << endl;
} //作用域也会触发析构函数
Myclass *m5 =new Myclass;
cout << Myclass::staticNumodInstance << endl;
delete m5; //会调用析构函数
cout << Myclass::staticNumodInstance << endl;
return 0;
}
继承
继承(inheritance)机制是面向对象程序设计使代码可以复用的最重要的手段,它允许程序员在保持原有类特性的基础上进行扩展,增加功能,这样产生新的类,称派生类。继承呈现了面向对象程序设计的层次结构,体现了由简单到复杂的认知过程。以前我们接触的复用都是函数复用,继承是类设计层次的复用。
#include <iostream>
using namespace std;
//基类,父类
class Vehicle{//交通工具,车,抽象的概念
public:
string type;
string contry;
string color;
double price;
int numOfWheel;
void run();
void stop();
};
//派生类, 子类
class Roadster : public Vehicle { //跑车,也是抽象,比父类感觉上范围缩小点 子类:public 父类 (因为或默认private)
public:
void openTopped();
void pdrifting();
};
int main()
{
Roadster ftype;
ftype.type ="捷豹Ftype";
return 0;
}