C++基础复习提升-const那些事

参考C++那些事-光城大佬的网站
下一篇C++基础复习提升-static那些事

1.1其他文件中调用(是/非)const定义的常量

其他文件调用const修饰的常量,需要借助extern关键字,非const修饰的常量则不需要在定义文件中使用extern关键字修饰也可调用。函数调用也是同理。

file1.txt定义
extern const int a = 100;
int b = 200;
file2.txt调用
extern const int a;
extern int b;

1.2const定义的常量必须要赋初始值

const定义的常量必须赋初始值,因为常量在定义后不能修改,所以定义时必须初始化。

1.3常量指针

常量指针指针的值不能改变

const int *ptr;

由于指针ptr指向的是const对象定义的int类型(也就是指向int类型的某块地址),const定义的是int类型的常量,而不是指针ptr本身,所以ptr可以不用赋初始值,但是不能通过ptr去修改所指对象的值。error写法:*ptr=10;

1.4使用const void*指针保存const对象的地址

注意不能使用void *指针来保存const对象的地址

const int p = 10;
const void *x = &p;
// 强转
const int *q = (const int*)x;

1.5将非const对象的地址赋给const对象的指针

const int *ptr;
int val;
ptr = &val;

1.6指向常量的指针通过非const对象指针改变const对象指针指向的地址的值

    // ptr指向int类型的const对象
    const int *ptr;
    // ext_value:10,ptr指向ext的地址
    ptr = &ext;
    // 打印ptr指向地址的值
    cout << *ptr << endl;
    // ptr1也指向ext的地址
    int *ptr1 = &ext;
    // 通过非const对象指针改变ext的值,从而改变ptr指向的值
    *ptr1 = 29;
    cout << *ptr << endl;

1.7常指针

常指针必须要赋初值,并且const指针的值不能改变(也就是指向的地址不能改变),但是指针ptr指向地址的值是可以变化的。

    // 指针常量(常指针)必须要赋初始值,且const指针指向的地址不能改变
    int *const ptr = &ext;
    *ptr = 200;

1.8常指针指向常量地址和变量地址

    const int num = 110;
    // 错误写法:int *const ptr = &num;
    // 上述错误原因是因为ptr是一个const指针指向了一个int类型的地址,指向的是一个变量地址,而不是一个const常量地址
    // 正确写法
    const int *const ptr = &num;

1.9常指针传参

void func(int *const val, const int *val2) {
	// 由于是常指针,所以const指针指向的地址不能变,但是指向的地址的值可以改变
	// 若要对实参进行保护,则传指针的常量参数,使之在函数中无法对实参进行修改
    *val = 109;
    val2 = val;
    cout << *val2 << endl;
}

int main() {
    // exp:10
    cout << exp << endl;
    // 传的是引用,改变形参影响实参
    func(&exp, &exp2);
    // exp:109
    cout << exp << endl;
    return 0;
}

1.10函数里传const对象引用提高效率和防止修改

void test(const A&a);

若使用引用效率低的原因是函数体首先会在内部产生A类型的临时对象用于复制参数a,这一过程就需要对临时对象进行构造,复制和析构,这将消耗大量时间。而引用传递仅仅是借用一下参数的别名,不会产生临时对象。
若参数是是非对象传递而不是对象传递,则不需要使用引用,采用值传递的形式,因为值传递不存在构造,析构的过程,复制也非常快,值传递和引用传递的效率相差无几,这种情况使用引用传递则会增加代码可读性的难度。

1.11类中const成员函数只能访问和操作const成员函数,不能操作(常/非常)成员变量但可以访问,非const对象可以访问任意成员函数,const对象不能访问操作非const函数,但是可以访问非const变量,可以操作static修饰的非const变量和函数

// file apple.cpp
using namespace std;

class Apple {
private:
    int people[100];
    int a = 120;
    int const b = 20;
public:
    Apple(int i);

    const int apple_number;

    void take(int num) const;

    int add(int num);

    int add(int num) const;

    void nonConstFunction();

    int getCount() const;
};
// file main.cpp
#include <iostream>
#include "apple.cpp"

using namespace std;

Apple::Apple(int i) : apple_number(i) {}

// 非const成员函数
int Apple::add(int num) {
    take(num);
    // correct: a = 20;非const成员函数可以对成员变量进行修改
    return num;
}

//const成员函数(常成员函数),提高程序的健壮性
int Apple::add(int num) const {
    take(num);
    //error:a = 300; const成员函数不能对成员变量进行修改
    return num + 1;
}


void Apple::nonConstFunction() { cout << "this is a non_const test file" << endl; }

void Apple::take(int num) const {
    cout << "take func:" << num << endl;
}

// 常函数只能访问常函数,不能访问非常函数,不能修改(非常/常)成员变量
int Apple::getCount() const {
    take(1);
    add(100);
    //error:a = 20; a是非常成员变量
    printf("apple_num:");
    return apple_number;
}

int main() {
    Apple a(2);
    cout << "get_count():" << a.getCount() << endl;
    // 非 常对象可以访问常成员函数,若没有重载非const函数add,则调用常函数add
    cout << "a.add():" << a.add(10) << endl;
    cout << "a.non_const():" << " ";
    a.nonConstFunction();
    cout << "--------------------------------------------" << endl;
    const Apple b(3);
    // 常对象只能操作常成员函数
    // 不能访问非const函数,error:例如b.nonConstFunction()是错误的
    cout << "b.getCount():" << b.getCount() << endl;
    cout << "b.add():" << b.add(110) << endl;
    return 0;
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值