C++基础精讲-06

发布于:2025-04-14 ⋅ 阅读:(46) ⋅ 点赞:(0)


1. this指针

1.1 this指针的概念

1.c++规定,this指针是隐含在对象成员函数内的一种指针。当一个对象被创建后,它的每一个成员函数都含有一个系统自动生成的隐含指针this,用以保存这个对象的地址。

2.this指针是C++实现封装的一种机制,它将对象和该对象调用的成员函数连接在一起,在外部看来,每一个对象都拥有自己的函数成员。一般情况下,并不写this,而是让系统进行默认设置。

3.本质:this指针的本质是一个常量指针 Type* const pointer; 它储存了调用它的对象的地址,不可被修改

3.注意:

(1)this指针永远指向当前对象。
(2)静态成员函数内部没有this指针,静态成员函数不能操作非静态成员变量。

//this:是指向当前对象的指针
//当前对象:谁调用这个函数,this指向谁;
//大多数情况下,this可以不写;
class Person
{
public:

    //构造函数
    Person():_age(0){}
    Person(int age):_age(age){}

    int  getAge()
    {
        return this->_age;
    }

private:
    int _age;
};

int main(void)
{
    Person p1(10);
    cout << p1.getAge() << endl;

    Person p2(20);
    cout << p2.getAge() << endl;
    return 0;
}

1.2 this指针的使用

1.当形参和成员变量同名时,可用this指针来区分

#include <iostream>
#include <cstring>

namespace myspace1
{
    using std::endl;
    using std::cout;
    using std::cin;
    using std::string;
}

using namespace myspace1;


//this:是指向当前对象的指针
//当前对象:谁调用这个函数,this指向谁;
//大多数情况下,this可以不写;

//使用
//1.当形参和成员变量同名时,可用this指针来区分


class Person
{
public:

    //构造函数
    Person():_age(0){}
    Person(int age):_age(age){}

    int  getAge()
    {
        return this->_age;
    }

    void setAge(int _age)
    {
        _age = _age;
    }

private:
    int _age;
};

int main(void)
{
    Person p1(10);
    cout << p1.getAge() << endl;
    p1.setAge(20);
    cout << p1.getAge() << endl;

    return 0;
}

在这里插入图片描述
可以看到,通过p1.setAge(20);并没有设置成功age的值;

void setAge(int _age)
{
    this->_age = _age;
}

在这里插入图片描述
通过this指针,就可以修改了;

2.在类的非静态成员函数中返回对象本身,可使用return * this.

#include <iostream>
#include <cstring>

namespace myspace1
{
    using std::endl;
    using std::cout;
    using std::cin;
    using std::string;
}

using namespace myspace1;


//this:是指向当前对象的指针
//当前对象:谁调用这个函数,this指向谁;
//大多数情况下,this可以不写;

//使用
//1.当形参和成员变量同名时,可用this指针来区分
//2.在类的非静态成员函数中返回对象本身,可使用return * this

class Person
{
public:

    //构造函数
    Person() :_age(0) {}
    Person(int age) :_age(age) {}

    //设置一个函数,累加上一个数字,返回对象本身
    Person& add(int age)
    {
        this->_age += age;

        //返回当前对象的引用
        return *this;
    }
    void print()
    {
        cout << this->_age << endl;
    }

private:
    int _age;
};

int main(void)
{
    Person p1;
    //每一次的函数调用,得到了自己(p1);
    p1.add(10).add(20);//链式调用
    p1.print();
    return 0;
}

2. 特殊的数据成员

2.1 常量数据成员

当数据成员用 const 关键字进行修饰以后,就成为常量成员。一经初始化,该数据成员便具有“只读属性”,在程序中无法对其值修改(C++11之后也允许在声明时就初始化)。

#include <iostream>
#include <cstring>

namespace myspace1
{
    using std::endl;
    using std::cout;
    using std::cin;
    using std::string;
}

using namespace myspace1;

class Poin
{
public:

    //构造函数
    Poin(int x, int y) :_x(x), _y(y)    //使用初始化列表来初始const数据成员
    {
        //错误,严格来说,这是赋值操作;
        /*_x = x;
        _y = y;*/
    }

    void print()
    {
        cout << "x=" << _x << endl;
        cout << "y=" << _y << endl;
    }

private:
    const int _x;
    const int _y;

    //c++11允许在声明时,给默认值
    /*const int _x = 1;
    const int _y = 2;*/
};

void test(void)
{
    Poin p1(10, 20);
    p1.print();

    //可以拷贝构造,但是不可以进行赋值操作;
    Poin p2 = p1;
}

int main(void)
{
    test();
    return 0;
}

2.2 引用数据成员

#include <iostream>
#include <cstring>

namespace myspace1
{
    using std::endl;
    using std::cout;
    using std::cin;
    using std::string;
}

using namespace myspace1;

//int z=10;

class Poin
{
public:

    //构造函数
    //z的生命周期不够长,_z是其他值;
    //解决办法
    //1.将z定义为全局变量
    //2.在定义时_z就绑定初值
    Poin(int x, int y,int z) :_x(x), _y(y),_z(z)
    {
      
    }

    void print()
    {
        cout << "x=" << _x << endl;
        cout << "y=" << _y << endl;
        cout << "z=" << _z << endl;
    }

private:
    int _x;
    int _y;
    int& _z;
    //int &z=z;   c++11标准
    
};

void test(void)
{
    Poin p1(1, 2, 3);
    p1.print();
}

int main(void)
{
    test();
    return 0;
}

2.3 静态数据成员

1.概念:
在一个类中,若将一个成员变量声明为static,这种成员称为静态成员变量。与一般的数据成员不同,无论建立了多少个对象,都只有一个静态数据的拷贝。静态成员变量,属于某个类,所有对象共享。
静态变量,是在编译阶段就分配空间,对象还没有创建时,就已经分配空间。
2.定义静态数据成员

class Pint {
public:
    static int n; // 声明静态数据成员
};

3.初始化静态数据成员

class Pint {
public:
    static int n; // 声明静态数据成员
};

// 在类外初始化静态数据成员
int Pint::n = 10;



void test(void)
{
    cout << "n= " << Pint::n << endl;
}

int main(void)
{
    test();
    return 0;
}

4.访问静态数据成员

class Pint {
public:
    static int n; // 声明静态数据成员
};

// 在类外初始化静态数据成员
int Pint::n = 10;



void test(void)
{
    // 通过类名访问静态数据成员
    cout << "n=" << Pint::n << endl;

    // 通过对象访问静态数据成员
    Pint p1;
    cout << "n=" << p1.n << endl;
}

5.使用场景
(1)共享数据:当多个对象需要共享某个数据时,可以使用静态数据成员。例如,统计类的对象创建的数量。
(2)常量数据:如果类中有一些常量数据,并且希望所有对象都能访问这些常量,可以将其定义为静态数据成员。

2.4 对象成员

1.概念:
C++ 里,对象成员指的是一个类将其他类的对象作为自身的数据成员。借助这种方式,能够构建复杂的类结构,达成代码的复用与模块化设计。

#include <iostream>
#include <cstring>

namespace myspace1
{
    using std::endl;
    using std::cout;
    using std::cin;
    using std::string;
}

using namespace myspace1;


//汽车类
class Car
{
public:
    //构造函数
    Car():_color(new char[strlen("白色")+1]),_price(0) {
        strcpy(_color, "白色");
        cout << "Car无参构造函数" << endl;
    }
    Car(const char *color,int price):_color(new char[strlen(color) + 1]), _price(0){

        strcpy(_color, color);
        cout << "Car有参构造函数" << endl;
    }
    //析构函数
    ~Car()
    {
        if (_color != nullptr)
        {
            delete[] _color;
            cout << "析构函数" << endl;
        }
    }
    //写
    void set(const char* color,int price)
    {
        strcpy(_color, color);
        _price = price;
    }
    //打印
    void print()
    {
        cout << "color=" << _color << endl;
        cout << "pice=" << _price << endl;
    }

private:
    char* _color;
    int _price;
};

//人类
class Person
{
public:

    //构造函数
    Person():_age(0){
        cout << "Person无参构造函数" << endl;
    }
    Person(int age):_age(age)
    {
        cout << "Person有参构造函数" << endl;
    }

    void setAge(int age)
    {
        _age = age;
    }

    void printPerson()
    {
        cout << "age=" << _age << endl;
        _c.print();
    }
    void setCar(const char* color, int price)
    {
        _c.set(color, price);
    }

private:
    Car _c;
    int _age;
};

void test()
{
    //Person 类的构造函数会先对其对象成员进行初始化,之后才执行自身构造函数体里的代码;
    Person p1(20);
    p1.setCar("黑色",20000);  //设置车辆信息
    p1.setAge(28);         //设置年龄
    p1.printPerson();
 
}

int main(void)
{
    test();
    return 0;
}

在这里插入图片描述

3. 特殊的成员函数

3.1 静态成员函数

1.概念:
在 C++ 中,静态成员函数是属于类而不是类的某个对象的成员函数。与普通成员函数不同,静态成员函数不依赖于特定的对象实例,它可以在没有创建任何对象的情况下被调用。
2.定义静态成员函数

//汽车类
class Car
{
public:
    //静态成员函数
    static void fun(void);
private:
    char* _color;
    int _price;
};

3.类外实现静态成员函数

//汽车类
class Car
{
public:
    //静态成员函数
    static void fun(void);
private:
    char* _color;
    int _price;
};
void Car::fun(void)
{
    cout << "我是静态成员函数" << endl;
}

4.调用静态成员函数
静态成员函数可以通过类名直接调用,也可以通过类的对象调用

//汽车类
class Car
{
public:
    //静态成员函数
    static void fun(void);
private:
    char* _color;
    int _price;
};
void Car::fun(void)
{
    cout << "我是静态成员函数" << endl;
}


void test()
{
    //通过类名调用
    Car::fun();

    //通过对象调用
    Car c1;
    c1.fun();
}

int main(void)
{
    test();
    return 0;
}

5.使用场景
(1)工具函数:当一些函数与类的对象状态无关,只是提供一些通用的功能时,可以将其定义为静态成员函数。
(2)管理类的静态数据成员:当需要对类的静态数据成员进行操作时,可以使用静态成员函数。例如,统计类的对象创建的数量,使用静态成员函数来获取或修改这个统计值。

6.总结
(1)静态成员函数不依赖于某一个对象;

(2)静态成员函数可以通过对象调用,但更常见的方式是通过类名加上作用域限定符调用

(3)静态成员函数没有this指针;

(4)静态成员函数中无法直接访问非静态的成员,只能访问静态数据成员或调用静态成员函数(因为没有this指针)。
(5)构造函数、拷贝构造、赋值运算符函数、析构函数比较特殊,可以在静态成员函数中调用。

3.2 const成员函数

1.概念
在 C++ 里,const 成员函数是一种特殊的成员函数,它承诺不会修改调用该函数的对象的状态
2.定义与语法

class Point {
private:
    int value;
public:
    Point(int val) : value(val) {}

    // 声明 const 成员函数
    int getValue() const;
};

// 定义 const 成员函数
//该函数内部不能修改对象的任何非静态数据成员。
int Point::getValue() const {
    return value;
}

int main() {
    const Point p1(10);
    cout << "Value: " <<p1.getValue() << endl;
    return 0;
}

3.使用场景
(1)访问器函数:当成员函数的主要目的是获取对象的某个属性值,而不修改对象的状态时,通常将其声明为 const 成员函数。
(2)在 const 对象上调用:如果你有一个 const 对象,那么只能调用该对象的 const 成员函数。因此,为了让 const 对象也能正常使用类的功能,需要将一些不修改对象状态的成员函数声明为 const 成员函数。

4.总结
(1)const 成员函数内部不能修改非静态数据成员
(2)const 成员函数和非 const 成员函数可以重载

3.3 mutable关键字

在 C++ 中,mutable 是一个关键字,它主要用于修饰类的数据成员。当一个数据成员被声明为 mutable 时,意味着即使在 const 成员函数中,该数据成员也可以被修改

class Point {
private:
    mutable int _value;
public:
    Point(int val) : _value(val) {}

    // 声明 const 成员函数
    int getValue() const;
};

// 定义 const 成员函数
int Point::getValue() const {

	//可以被修改
    _value = 100;
    return _value;
}

int main() {
    const Point p1(10);
    cout << "Value: " <<p1.getValue() << endl;
    return 0;
}

在这里插入图片描述


网站公告

今日签到

点亮在社区的每一天
去签到