C++(面向对象编程——关键字)

思维导图

关键字

1.this指针

1.1 什么是this指针?

this指针是一种特殊的指针,在类内指向当前类的外部对象。在类的成员函数中,可以使用this指针来访问当前对象的成员变量和成员函数。通过this指针,可以避免在成员函数中使用与参数名或局部变量同名的成员变量时产生歧义。在类的成员函数中,this指针始终指向调用该函数的对象。可以这样理解,this代指当前操作的对象。

下面这个程序就会发现,类内调用的this指针和对象的地址是一样的。

cpp 复制代码
#include <iostream>
#include <string>

using namespace std;

class Techer{
private:
    int age;
    string name;
public:
    Techer(int a,string n){
        age = a;                      
        name = n;
    }
    void print(){
        cout << this << endl;
    }
};

int main (){
    Techer t1(45,"xiaowang");
    t1.print();
    cout << &t1 << endl;
    return 0;
}

1.2 对象调用成员

成员:成员变量成员方法

成员必须由对象调用。

下面这段代码,思考一下,之前我们在类内为什么能直接调用类内函数和类内变量,其实这都是编译器在帮助我们优化,原型是类内变量和类内方法前面加上this->。

cpp 复制代码
class Techer{
private:
    int age;
    string name;
public:
    Techer(int a,string n){     
        age = a;
        name = n;
        //this.age = a;                //原型                  
        //this.name = n;                //原型
    }
    void print1(){
        cout << age << endl;
        //cout << this->age << endl;        //原型
    }
    void print2(){
        print1();
        cout << name << endl;
        //this->print1();                    //原型
        //cout << this->name << endl;        //原型
    }
};

1.3 成员变量与局部变量命名冲突问题

当我们成员变量和局部变量命名冲突的时候,这个时候编译器就不知道如何优化,这个时候就会发生错误。比如下面这样写:

cpp 复制代码
class Techer{
private:
    int age;
    string name;
public:
    Techer(int age,string name){     
        age = age;                      //二义性,此时编译器不知道如何处理
        name = name;
    }
    void print(){
        cout << age << " " << name << endl;
    }
};

所以只要我们的代码没有二义性,就可以解决,这里有两种解决方法:

(1)在有明确是类内变量的前面加上this->明确告诉编译器类内变量。

cpp 复制代码
class Techer{
private:
    int age;
    string name;
public:
    Techer(int age,string name){     
        this->age = age;                      //二义性,此时编译器不知道如何处理
        this->name = name;
    }
    void print(){
        cout << age << " " << name << endl;
    }
};

(2)构造初始化列表。

这个时候,编译器明确规定只能把()内的局部变量复制给外面的成员变量,消除二义性

cpp 复制代码
class Techer{
private:
    int age;
    string name;
public:
    Techer(int age,string name):age(age),name(name){     
    }
    void print(){
        cout << age << " " << name << endl;
    }
};

1.4 链式调用

如果一个成员的返回值类型是当前类型应用,则这个这个函数支持链式调用,函数体重一定return *this。加引号就是直接修改当前对象,如果不加引号,就是返回新对象并把新对象拷贝为当前对象。

cpp 复制代码
#include <iostream>
#include <string>

using namespace std;

class Techer{
private:
    int age;
    string name;
public:
    //初始化构造函数
    Techer(int a,string n){
        age = a;
        name = n;
    }
    //拷贝构造函数
    Techer(Techer &t){
        age = t.age;
        name = t.name;
        cout << "拷贝" << endl;
    }
    //获取当前年龄
    int get_age(){
        return age;
    }
    //年龄累加,返回当前对象
    Techer& addage(int a){
        age += a;
        return *this;
    }
    //不加引用会多次拷贝
    Techer addage2(int a){
        age += a;
        return *this;
    }
};

int main (){
    Techer t1(45,"xiaowang");
    cout << t1.addage(1).addage(2).addage(3).addage(4).get_age() << endl;
    cout << "################" << endl;
    cout << t1.addage2(1).addage2(2).addage2(3).addage2(4).get_age() << endl;
    return 0;
}

2.static关键字

2.1 静态局部变量

static 可以修饰局部变量,这样的局部变量就是静态局部变量。当函数第一次被调用 的时候,创建这个静态局部变量,函数执行完后不会销毁,下次使用函数直接使用该静态局部变量。

局部静态变量属于于函数,只有函数可以访问它,生命周期延长但是作用于还在函数内

cpp 复制代码
#include <iostream>
#include <string>

using namespace std;

class Techer{
private:
    int age;
    string name;
public:
    Techer(int age,string name):age(age),name(name){}
    int add(){
        static int a = 2;
        return ++a;
    }
};


int main (){
    Techer t1(45,"xiaowang");
    cout << t1.add() << endl;
    cout << "################" << endl;
    cout << t1.add() << endl;
    //cout << a << endl;          //局部静态变量属于于函数,只有函数可以访问它,生命周期延长但是作用于还在函数内
    return 0;
}

2.2 静态成员变量

使用static修饰的成员变量被称为静态成员变量 ,非const的静态成员变量不能被初始化,只有"const static int a = 1"这样才能初始化,这就有一个问题,都常量化了我创建它有什么意义。这个时候就可以在类内声明,类外初始化。类似于C语言的全局变量。哪里都可以用,但是必须加上作用域限定符,让编译器明白,你调用的是哪个静态成员变量。这个时候你创建的静态成员变量,整个程序就这一个,不管你创建多少个对象,多个对象共用这个静态成员变量。

cpp 复制代码
#include <iostream>
#include <string>

using namespace std;

class Techer{
private:
    int age;
    string name;
public:
    Techer(int age,string name):age(age),name(name){}
    //const static int a = 1;            //常量化静态成员变量
    static int a;       //类内声明
    int b = 1;
};

int Techer::a = 1;      //类外初始化

int main (){
    Techer t1(45,"xiaowang");
    Techer t2(40,"zhangsan");
    cout << t1.a++ << endl;        //t1和t2一起公有的a
    cout << t1.a++ << endl;
    cout << t1.b++ << endl;        //t1独有的b
    cout << t1.b++ << endl;
    cout << "################" << endl;
    cout << t2.a++ << endl;
    cout << t2.a++ << endl;
    cout << t2.b++ << endl;
    cout << t2.b++ << endl;
    cout << "################" << endl;
    cout << Techer::a << endl;
    return 0;
}

2.3 静态成员函数

使用static修饰成员函数就是静态成员函数 ,静态成员函数简单来说就是可以脱离类单独使用,类似于静态成员变量,但是也必须添加**作用域限定符,**让编译器明白你调用的函数是那个类的。这个时候静态成员函数就相当于C语言中的函数一样使用.

cpp 复制代码
#include <iostream>
#include <string>

using namespace std;

class Techer{
private:
    int age;
    string name;
public:
    Techer(int age,string name):age(age),name(name){}
    static int add(int a,int b){    //静态成员函数
        return a + b;
    }
};

int add(int a,int b){            //正常函数
        return a + b;
    }


int main (){
    Techer t1(45,"xiaowang");
    cout << t1.add(5,5) << endl;
    cout << "################" << endl;
    cout << Techer::add(4,5) << endl;
    cout << "################" << endl;
    cout << add(3,4) <<endl;                //调用全局函数不用加作用域限定符,不过你也可以把函数放到一个namesapce名字空间里
    return 0;
}

3.const关键字

3.1 const成员函数

使用const修饰成员函数,表示常成员函数,这样的函数无法修改成员变量值,不能调用其他非const修饰的成员变量函数。

只要不修改成员变量的成员函数都加上const修饰。

cpp 复制代码
#include <iostream>
#include <string>

using namespace std;

class Techer{
private:
    int age;
    string name;
public:
    Techer(int age,string name):age(age),name(name){}
    int get_age()const{
        return age;
    }
    string get_name()const{
        return name;
    }
    void print()const{            //不能调用不是const修饰的函数
        cout << get_age() << endl;
        cout << get_name() << endl;
    }
};

int main (){
    Techer t1(45,"xiaowang");
    t1.print();
    return 0;
}

3.2 const对象

被const修饰的对象,即使成员变量放在公共区域,也不能被修改,也不能调用不是const修饰的成员函数。下面两种当时都可以定义一个const对象。

cpp 复制代码
    const Techer t1(32,"lisi");
    Techer t1 const(32,"lisi");

3.3 const成员变量

const修饰的成员变量表示常成员变量,这样的成员变量不能被修改。只要一旦定义了这个const对象,就不能修改成员变量,初始化的时候是可以重新赋值的。

(1).声明的时候直接赋值:

cpp 复制代码
#include <iostream>
#include <string>

using namespace std;

class Techer{
private:
    const int age = 45;
    const string name = "zhangsna";
public:
    int get_age()const{
        return age;
    }
    string get_name()const{
        return name;
    }
    void print()const{
        cout << get_age() << endl;
        cout << get_name() << endl;
    }
};

int main (){
    Techer t1;
    t1.print();
    cout << t1.get_age() << endl;
    return 0;
}

(2).构造初始化列表:

cpp 复制代码
#include <iostream>
#include <string>

using namespace std;

class Techer{
private:
    const int age = 45;
    const string name = "zhangsna";
public:
    Techer(int age,string name):age(age),name(name){}
    int get_age()const{
        return age;
    }
    string get_name()const{
        return name;
    }
    void print()const{
        cout << get_age() << endl;
        cout << get_name() << endl;
    }
};

int main (){
    Techer t1(34,"zhangsan");
    t1.print();
    cout << t1.get_age() << endl;
    return 0;
}
相关推荐
微信公众号:AI创造财富2 小时前
conda create -n modelscope python=3.8 conda: command not found
开发语言·python·conda
鱼会上树cy2 小时前
空间解析几何10:三维圆弧拟合【附MATLAB代码】
开发语言·matlab
IT艺术家-rookie2 小时前
golang--channel的关键特性和行为
开发语言·后端·golang
凌肖战2 小时前
力扣网C语言编程题:三数之和
c语言·算法·leetcode
心软且酷丶4 小时前
leetcode:263. 丑数(python3解法,数学相关算法题)
python·算法·leetcode
我最厉害。,。4 小时前
C2远控篇&C&C++&ShellCode分离&File提取&Http协议&Argv参数&Sock管道
c语言·c++·http
大龄Python青年4 小时前
C语言 函数怎样通过数组来返回多个值
c语言·开发语言
LQYYDSY4 小时前
【C语言极简自学笔记】重讲运算符
c语言·开发语言·笔记