const

本文详细解析了C++中的const关键字,包括其在指针、函数、对象、成员函数等场景的应用,以及与宏定义的区别和实现机制。

const 之 指针 篇

常量指针 / 常指针

常量指针本质上是指针,表示指向常量的指针(变量)。
一般“常指针”也指常量指针。

声明方式如下: const T *A; or T const *A;
const修饰指向的对象,指针A可变,A指向的对象不可变。
所谓指向的对象不可变,指的是不能通过该指针去修改指向对象的内容,性质上等同于一个只读指针。但是可以通过所指向对象本身去修改内容。

比如:

int a;
iut c;
cosnt int *b = &a;
a = -1;   //正确,通过变量a本身去修改内容是合法的
*b = -1;  //错误,通过指针b去修改指向对象的内容是不合法的
b = &c;	//正确,b是指针,可以修改本身的值

另外,由以上例子也可以看出,常量指针(指向常量的指针)也可以指向变量。

指针常量

指针常量本质上是常量,即一个指针类型的常量。声明的时候必须初始化。

声明方式: T *const A;
const修饰指针A,A不可变,A指向的对象可变。

比如:

int a = 1, int c;
int *const b = &a;
*b = -1;   //正确,指针b指向的对象可变,内容可修改
b = &c;   //错误,本质上是常量,不可以修改指向的对象

常指针常量

声明方式如下:
const T *const A;
显而易见,指针A和A所指向的对象都不可改变。


const 之 函数 篇

const 修饰 函数参数

const引用,通常应用于定义变量的只读属性的别名,作为函数传入形参,避免在调用函数中意外地被改变。const引用是只读的,常量不能作为左值。

const修饰对象变量(非常量)传入形参( 输出形参不能用const修饰),因为不会产生临时变量,节省了临时对象构造,复制,析构的过程,可提高程序效率。但是对于内部数据类型,没有构造,析构的消耗,复制过程也非常快,因此“值传递”与“引用传递”的效率几乎一样。

const的引用及初始化

对一个常量进行引用,编译器会首先建立一个临时变量,然后将该变量的值置入临时变量中,对该引用的操作就是对该临时变量的操作,对常量的引用可以用其他任何引用来初始化,但是不能改变。

当初始化值是一个左值(可以取得地址)时,没有任何问题;而当初始化值不是一个左值时,则只能对一个常引用赋值,而且赋值的过程是,首先将值隐式转换到类型T,然后将这个转换结果存放在一个临时对象里,最后用这个临时对象初始化该引用变量。

比如:

 1). double &dr = 1;            //错误,初始化值不是左值
 2). const double &cdr = 1;     //正确

其中,第二种方法对应的执行过程如下:

double temp = double(1);
const double &cdr = temp;

如果将第一种方法改为合法操作,对应如下:

const int ival = 1024;
const int &refval = ival;

在使用const引用进行函数调用时,即作为函数传入形参,需注意:

#include<iostream>
#include<string>
using namespace std;

void bar(string &s){
	cout<<s<<endl;
}

int main(){
	bar("hello world");              //非法操作
	/* string s = "hello world";
	bar(s);*/                       //传入的是变量,合法
	return 0;
}

原因:

“hello world”串会产生一个临时变量,而在c++中,临时对象都是const类型的,因此该表达式试图将一个const类型的对象转换为非const类型,这是非法的。
应该改为将函数声明改为bar(const string &s);
或者采用值传递bar(stirng s);

const 修饰 函数返回值

const修饰函数返回值,表示返回值(即指针或引用)的内容不能修改。

之所以一定是指针或引用,是因为函数返回值采用“值传递”的方式,则返回值存储于外部临时变量,const修饰没有任何意义。

一般采用引用返回的方式比较少见,常见于类的赋值函数,目的是为了实现链式表达,即A = B = C;

普通情况下,(A = B) = C;的表达不常见,但是合法。但是const修饰的函数返回值该操作会报错,因为const常量只能有一次初始化,不能作为左值进行赋值操作。


const 之 类 篇

const 修饰 数据成员

结合关键字static,对数据成员的初始化进行分析,主要有以下几种:

非静态数据成员(const T)
class example{
	private:
		const int count;
	public:
		example() = default;
		example(const int &count):count(count){};         //只能初始化列表初始化
};

非静态常量数据成员不能在类内初始化,即不能在声明时初始化,也不能在构造函数中初始化,只能在构造函数的初始化列表中初始化。因此,非静态数据成员必须要有构造函数
1)因为const常量数据成员只能有一次初始化的过程,若在构造函数内部或是在类外,都是对已经完成构造的对象数据成员进行赋值而不是初始化。
2)不同的对象const数据成员的数据可以不同,对象没被创建时,编译器不知道值是什么。

静态非常量数据成员(static T)
class example{
	private:
		static int count;
};
int example::count = 0;        //只能类外初始化,不用再加static关键字

静态非常量数据成员不能在类内初始化,且只能在类外初始化,初始化时不必再加static关键字。
因为static数据成员是所有类对象共享的,在全局数据空间中仅存在一份实例,若是在类内初始化,则每个对象都会包含一个该数据成员,这是矛盾的。

静态常量数据成员(static const T)
class example{
	private:
		static const int count = 0;
};
//const int count = 0;

静态常量数据成员既可以在类内初始化,也可以在类外初始化

const 修饰 成员函数

const修饰成员函数由两种形式:

  1. 当const位于函数前,即const T *Funtional(){};表示修饰函数返回值(见函数篇);
  2. 当const位于函数后,即T Funtional() const{};表示修饰该函数的this指针;

每个const成员函数都有隐含的指针参数(class)A * const this;const修饰指针this,表示该成员函数不会修改类的数据,否则编译报错。
const函数可以访问普通成员变量,但是不能修改。除非该数据成员声明有mutable关键字。


const 与 #define(宏定义)

编译器处理

#define在预处理阶段展开(编译阶段替换),无法进行调试;
const常量于编译阶段运行时使用,可用某些集成化的工具调试。

类型

#define是简单的类型替换,没有数据类型,因此替换也没有类型安全检查,可能产生边际效应,出现错误;
const常量则有具体的数据类型,在编译阶段进行类型安全检查。

存储与内存分配

#define在预处理阶段展开,不会分配内存(预处理展开,编译替换才分配内存)
const常量编译阶段使用,需要分配内存。
宏定义存储于程序的代码段,而const常量存储于程序的data段。

#define PI 3.1415			//宏定义常量
const double pi = 3.1415;	//const定义,并未将Pi置入只读存储器
double I = PI;				//为PI分配内存,仅此一次,以后不再分配
doubel i = pi;				//编译替换,每次替换均分配内存

从汇编的角度看,const定义常量只是给出了对应的地址,而不是像#define一样给出的是立即数,所以const常量在程序运行过程中只有一份拷贝,而#define定义的常量在内存中由若干拷贝。


const 之 实现机制

const 之 实现机制(借鉴,原理待求证)

const只是编译阶段的保护,编译期间会检查const变量有没有被修改,如果有代码尝试修改,编译报错。const一定程度上在编译阶段使得该变量成为一个常量,但是并没有实现保证该变量在运行阶段内存中的值不被修改。
const关键字是用于约束程序员和编译器为的,而不是程序员用以保证程序正确性的良药,除了全局常量外,没有任何机制保证const声明的常量的不可修改性。

一、 内容概要 本资源提供了一个完整的“金属板材压弯成型”非线性仿真案例,基于ABAQUS/Explicit或Standard求解器完成。案例精确模拟了模具(凸模、凹模)与金属板材之间的接触、压合过程,直至板材发生塑性弯曲成型。 模型特点:包含完整的模具-工件装配体,定义了刚体约束、通用接触(或面面接触)及摩擦系数。 材料定义:金属板材采用弹塑性材料模型,定义了完整的屈服强度、塑性应变等真实应力-应变数据。 关键结果:提供了成型过程中的板材应力(Mises应力)、塑性应变(PE)、厚度变化​ 云图,以及模具受力(接触力)曲线,完整再现了压弯工艺的力学状态。 二、 适用人群 CAE工程师/工艺工程师:从事钣金冲压、模具设计、金属成型工艺分析与优化的专业人员。 高校师生:学习ABAQUS非线性分析、金属塑性成形理论,或从事相关课题研究的硕士/博士生。 结构设计工程师:需要评估钣金件可制造性(DFM)或预测成型回弹的设计人员。 三、 使用场景及目标 学习目标: 掌握在ABAQUS中设置金属塑性成形仿真的全流程,包括材料定义、复杂接触设置、边界条件与载荷步。 学习如何调试和分析大变形、非线性接触问题的收敛性技巧。 理解如何通过仿真预测成型缺陷(如减薄、破裂、回弹),并与理论或实验进行对比验证。 应用价值:本案例的建模方法与分析思路可直接应用于汽车覆盖件、电器外壳、结构件等钣金产品的冲压工艺开发与模具设计优化,减少试模成本。 四、 其他说明 资源包内包含参数化的INP文件、CAE模型文件、材料数据参考及一份简要的操作要点说明文档。INP文件便于用户直接修改关键参数(如压边力、摩擦系数、行程)进行自主研究。 建议使用ABAQUS 2022或更高版本打开。显式动力学分析(如用Explicit)对计算资源有一定要求。 本案例为教学与工程参考目的提供,用户可基于此框架进行拓展,应用于V型弯曲
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值