CPP基础(2)

发布于:2025-06-11 ⋅ 阅读:(22) ⋅ 点赞:(0)

引用

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;
}