首页 > 编程语言 >C++ const关键字

C++ const关键字

时间:2024-05-25 11:06:52浏览次数:16  
标签:const 常量 constexpr int C++ 关键字 指针 函数

C++ const关键字

记得有次面试carmera turning岗,面试官让我谈谈const关键字的作用我提到被const修饰变量会存入.rodata的只读数据段不可更改,面试官好像不是很满意,现在想想carmera turning岗位好像主要用C++,面试官当时是想让我说说C++中const关键字的作用。C++中const关键字的作用比起C语言就多了不少。

1. 用于声明常量

常量一旦被初始化,就不能被修改。在C++中被const修饰的变量仅在当前文件中可见

const int MAX_SIZE = 100; // 声明一个常量
MAX_SIZE = 200; // 错误:常量不能被修改

2. 指向常量的指针

指向常量的指针表示指针所指向的值是常量,不能通过指针修改该值。

const int* ptr; // 指向常量的指针
int value = 5;
ptr = &value;
// *ptr = 10; // 错误:不能通过指针修改常量值

3. 常量指针

常量指针表示指针本身是常量,不能改变指针指向的地址。

int value = 5;
int* const ptr = &value; // 常量指针
*ptr = 10; // 合法:可以通过常量指针修改指针指向的值
// ptr = nullptr; // 错误:不能改变常量指针的指向

4. 常量成员函数

成员函数的末尾增加一个const会变为常量成为函数,这个成员函数不会修改该对象里面的任何成员变量的值等。

void noone() const
{
    Hour += 10;   //错误,常量成员函数不可以修改成员变量值
}

注意:

普通函数(非成员函数)末尾是不能加const的。

成员函数的声明和实现代码分开的情形下,不但要在成员函数的声明中增加const,也要在成员函数的实现中增加const。

5.常量对象

const MyClass obj;
obj.display();

被const修饰的对象,只能调用常量成员函数,且不能修改成员变量。

mutable

被mutable修饰的成员变量永远处于可变状态,即使是在常量成员函数中。引入mutable关键字的意义在于,满足在某些情况下需要常量对象,调用常量成员函数修改一些特定值的情况。

class Time {
private:
    mutable int myHour;    // 允许在const成员函数中修改
    int myMinute;
    int mySecond;

public:
    void noon() const {
        myHour = 12;  
    }
};

6.修饰函数参数

输入参数采用“指针传递”加 const 修饰可以防止意外地改动该指针,起到保护作用。

void StringCopy(char *strDestination, const char *strSource);

常量左值引用

void Func(const A &a)。

相较于void Func(A a)的写法上面的写法传入引用省去了临时对象的构造、复制、析构过程,加入const变为常左值引用防止参数被意外修改,而且既可以接受左值引用,又可以接受右值引用,增加程序的通用性。

7.修饰函数返回值

const 修饰内置类型的返回值,修饰与不修饰返回值作用一样。

#include<iostream>
 
using namespace std;
 
const int Cmf()
{
    return 1;
}
 
int Cpf()
{
    return 0;
}
 
int main(void)
{
    int _m = Cmf();
    int _n = Cpf();
 
    cout<<_m<<" "<<_n;
    system("pause");
    return 0;
}

const 修饰自定义类型的作为返回值,此时返回的值不能作为左值使用,既不能被赋值,也不能被修改。

#include <iostream>

class MyClass {
public:
    MyClass(int value) : value_(value) {}
    int getValue() const { return value_; }
    void setValue(int value) { value_ = value; }

private:
    int value_;
};

// 返回一个const MyClass对象的引用
const MyClass getConstObject() {
    static MyClass obj(10);
    return obj;
}

int main() {
    //不可被赋值
    MyClass newObj(20);
    getConstObject() = newObj;
    //不可被修改
    getConstObject().setValue(20); 
    //不可作为左值
    MyClass& objRef = getConstObject();
    return 0;
}

const 修饰指针作为返回值,函数返回值(即指针)的内容不能被修改,该返回值只能被赋给加 const 修饰的同类型指针。

const int* getConstPointer() {
    static int* a;
    return a;
}

int main() {
    const int* p = getConstPointer();//不能去掉const
    return 0;
}

constexpr

constexpr 变量在编译时必须能够求值。这意味着编译器在编译时就可以确定该变量的值。

constexpr int max_size = 100; // 编译时常量

constexpr 函数

constexpr 函数是一种在编译时可以计算其返回值的函数。为了成为 constexpr 函数,该函数必须满足一些条件,例如函数体必须包含一个返回语句,并且所有参与计算的参数和操作都必须是编译时可知的。

constexpr int factorial(int n) {
    return (n <= 1) ? 1 : (n * factorial(n - 1));
}

在上面的例子中,factorial 函数在编译时即可计算其结果:
constexpr int result = factorial(5); // result 在编译时计算出 120

constexpr 构造函数

在 C++11 及其后的标准中,构造函数也可以被标记为 constexpr,这允许在编译时创建常量表达式对象。

class Point {
public:
    constexpr Point(double x = 0, double y = 0) : x_(x), y_(y) {}
    constexpr double getX() const { return x_; }
    constexpr double getY() const { return y_; }
private:
    double x_;
    double y_;
};

constexpr Point p(3.0, 4.0);
constexpr double x = p.getX(); // x 在编译时计算出 3.0
constexpr double y = p.getY(); // y 在编译时计算出 4.0

constexpr 和 const 的区别

const 仅表示对象不可修改,但不要求编译时求值。
constexpr 要求表达式在编译时求值,因此可以用于定义编译时常量。
constexpr 的限制
为了使函数成为 constexpr,需要满足以下条件:

函数必须有一个返回值。
函数体必须是一个编译时常量表达式。
参数和返回值都必须是字面值类型(literal types)。

标签:const,常量,constexpr,int,C++,关键字,指针,函数
From: https://www.cnblogs.com/cuberxh/p/18212156

相关文章

  • 【C++】C++异常处理精要:从传统C语言错误处理到现代C++异常机制
    文章目录前言:1.C语言传统的处理错误的方式2.什么是异常处理机制?3.C++异常处理语法3.1.异常抛出(Throw)3.2.异常捕获(Catch)3.3.异常传递(ExceptionPropagation)3.4.异常规范(ExceptionSpecification)3.5.异常安全(Exceptionsafe)4.C++异常处理的最佳实践4.1.只在必......
  • C++ 组含子项自定义排序通用设计
    #include<memory>classBase;usingBaseSp=std::shared_ptr<Base>;classBase{public:  explicitBase(intid):ID(id){}  intID;};classSorter{public:  virtualboolsort(constBaseSp&l,constBaseSp&r){returntrue;......
  • 在 C++ 中 auto什么意思
    在C++中,是一个关键字,用于声明自动类型推断变量。它允许编译器根据变量初始化的表达式来推断其类型,从而减少代码中的类型冗长,提高代码的可读性和编写效率。auto使用声明的变量可以在编译时确定其类型,而不是在编写代码时显式指定类型。这在某些情况下可以简化代码,特别是当变......
  • 【C++】牛客——OR64 求和
    ✨题目链接:OR64求和✨题目描述 输入两个整数n和m,从数列1,2,3.......n中随意取几个数,使其和等于m,要求将其中所有的可能组合列出来✨输入描述:每个测试输入包含2个整数,n和m✨输出描述: 按每个组合的字典序排列输出,每行输出一种组合 ✨示例1......
  • java第九课(object类,final关键字,String类)
    1.object类在我们平时创建一个类的时候往往我们明明什么内容都没有写,但是他缺有很多的方法?其实我们所书写的所有类都默认继承了一个类,这个类就是Object类。object类又叫万类之祖,因为在java中如果没有写继承的话,那么就默认这个类继承Object类,例如,以下定义完全相同。classPe......
  • STL 以及 C语言与C++的区别
    C++语言的标准库(STL)容器(Containers)vector:动态数组,可以动态增长和收缩,支持快速随机访问元素。list:双向链表,支持在任意位置快速插入和删除元素。map:关联容器,以键值对(key-value)形式存储元素,支持快速查找和插入。竞赛常用C++STL用法https://io.zouht.com/154.htmlv......
  • c++ 设计模式:建造者模式
    建造者模式(BuilderPattern)是一种创建型设计模式,它允许你构造复杂对象步骤分解。你可以不同的步骤中使用不同的方式创建对象,且对象的创建与表示是分离的。这样,同样的构建过程可以创建不同的表示。举例说明:#include<iostream>//#include<map>//#include<stack>#include<......
  • C++友元和动态内存
    在C++中,友元机制允许一个类将其非公有成员的访问权限授予指定的函数或者类。然而,滥用友元会破坏封装性,导致可维护性和安全性问题。动态内存指的是在程序运行时分配和释放内存,通常通过使用new和delete操作符在C++中管理。下面是一个简单的例子,展示了如何在类中使用友元函数来访问......
  • C++/Qt桌面应用学习路线参考
    ......
  • c++对象存放区域
    在C++中,对象的存放位置通常取决于对象的生存周期和分配方式。C++中的对象可以存放在以下几个主要的内存区域:栈(Stack):自动变量和局部对象通常存储在栈上。栈是一种后进先出(LIFO)的数据结构,它由编译器自动管理,当函数调用结束时,栈上的局部对象会自动被销毁。堆(Heap):动态分配......