Java中的final 和 C++中的final

📅 2026/7/2 18:57:26
Java中的final 和 C++中的final
修饰变量final变量是不可改变的但它的值可以在运行时刻初始化也可以在编译时刻初始化甚至可以放在构造函数中初始化而不必在声明的时候初始化所以下面的语句均合法final int i 1; // 编译时刻 final int i2 (int)(Math.Random() * 10); //运行时刻 final int i3; //构造函数里再初始化final经常和static一起用这种用法类似C的常量在Java中很常见比如static final i 10;但这里同样也是允许运行时刻初始化的。修饰类对象而如果修饰类对象并不表示这个对象不可更改而是表示这个这个变量不可再赋成其它对象这就比较像 C的Class const * p了(这样表明这个指向该Class的指针p不能再指向其他对象指针常量但是该对象中的值是可以修改的(const Class *p是常量指针任何成员变量都不能修改))。final Value v new Value(); v new Value(); //不允许 v.some_method(); //允许修饰方法final修饰的方法是不能被重载的类似于类中的private方法所以private方法默认是final的大致说就是变量不可修改基本数据类型值不能修改类类型引用不能修改方法不可重载类不可继承C中final只有两种修饰类修饰虚函数C中constC中的const用处很多包括常量声明、变量修饰、常量引用、指针与const的组合、以及常量对象、成员函数。修饰变量(基本类型变量、成员变量)修饰基本类型变量修饰变量也可以叫作常量的声明使用const关键字可以修饰变量一旦初始化后就不能再修改其值。const int MAX 123; const double PI 3.14; const int x 334;以上的MAX、PI、x将都不能再修改其值const定义的常量和#define宏定义的常量的区别const常量有数据类型define宏定义常量没有编译器会对const常量可以进行数据类型的安全检查但是对于define宏定义编译器只是将其进行字符替换这样的字符替换很容易出错。比如以下代码如果使用不加括号的宏定义将不能正确计算(ab)/5.0而是变成计算a(b/5.0)了。//define宏定义的做法 #define a 2.0 #define b 9.0 #define c1 ab //不好的定义方法 #define c2 ((a)(b)) //推荐的定义方法 void func1(void) { float d1 c1/5.0; //本意是想计算(ab)/5.0但字符替换使计算变成了ab/5.0 float d2 c2/5.0; //正确计算了((a)(b))/5.0 (ab)/5.0 } //推荐的const常量的做法 const float a 2.0; const float b 9.0; const float c a b; void func2(void) { float d c/5.0; //正确计算了(ab)/5.0 }修饰成员变量在类中使用const修饰的成员变量只能在初始化列表中进行初始化并且不能在构造函数中修改其值。class MyClass { public: const int x; MyClass(int value) : x(value) {} // 初始化const修饰的成员变量 };这段代码定义了一个类MyClass其中有一个const修饰的整型成员变量x。在构造函数的初始化列表中对x进行初始化且只能在初始化列表中初始化不能在构造函数内部修改其值。const与引用const引用可以绑定到临时对象或字面量延长其生命周期。用这种方式声明的引用不能通过引用对目标变量的值进行修改,从而使引用的目标成为const达到了引用的安全性。const int ref 10; // 合法 // int ref2 10; // 非法非常量引用不能绑定字面量 int x 10; const int a x; x 5;const与指针const在*前数据不能改const在*后指针不能改常量指针形式const type* ptr(推荐) 或type const* ptr这里可以理解为 const修饰的是type类型的数据(const type)* ptr 或 (type const)* ptr也就是说不能通过ptr修改值但ptr可以指向其他地址。int a 10, b 20; const int* ptr a; *ptr 30; // 错误不能修改指向的数据 ptr b; // 正确可以改变指针指向const在*前数据不能改指针常量形式type* const ptr这里可以理解为const修饰的是ptr也就是说ptr一旦初始化指向之后就不能指向其他地址但可以通过指针修改所指向的数据。int a 10, b 20; int* const ptr a; *ptr 30; // 正确可以修改a的值 ptr b; // 错误不能改变指针指向const在*后指针不能改指向常量 的 常量指针形式const type* const ptr或type const* const ptr既不能修改指针指向也不能通过指针修改数据。int a 10, b 20; const int* const ptr a; *ptr 30; // 错误 ptr b; // 错误const在函数中的应用const形参避免函数内意外修改参数常用于指针或引用传参。void print(const int* arr, int size) { for (int i 0; i size; i) std::cout arr[i] ; // 只读访问 }const成员函数const修饰类成员函数实际修饰该成员函数隐含的this指针表明在该成员函数中不能对类的任何成员进行修改。class MyClass { int value; public: int getValue() const { return value; } // 不会修改对象状态 };const返回值也是用const来修饰返回的指针或引用保护指针指向的内容或引用的内容不被修改也常用于运算符重载。函数三种返回类型返回值、返回引用()、返回指针(*)返回值现在返回值使用const几乎没有意义例如const int ten(){ return 10; //返回值是一个临时对象 } //在后续的赋值中 const int x ten();在c11之后临时对象本来就不能被修改所以const int ten()和int ten()本质上效果一样。返回引用或者指针这里用引用举例指针一样的道理引用返回值不是重新创建一个对象而是直接把函数内部或外部某处的对象引用返回给调用者这样将不会产生对象拷贝性能高调用者直接访问的就是原对象。给引用加const可以保护原对象不被调用者修改例如class A { public: int getValue2(){ return m_value; } const int getValue(){ return m_value; } private: int m_value 10; }; int main() { A a; a.getValue() 100; //不允许修改 a.getValue2() 111; //直接修改成员 }getValue()将不允许修改成员变量m_value而getValue2()将会直接修改成员变量m_value;一般get函数会被const修饰const int getValue const(){return m_value}这样函数内的成员变量也会被const修饰不允许修改。在返回const引用要注意返回对象的生命周期必须比函数长例如const int backNum() { int num 1; return num; //错误num会在函数结束后消失这块内存的位置也会给其他变量用 } void otherFunc() { int a 100;