CPP基础(2)
引用
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;
}