正如我所看到的,C ++常量指针,C ++参考和Java final关键字(最终变量)都是相同的东西,或者至少以相同的方式起作用。
它们防止变量更改其“指向的地址”,但可以更改内部值。
我对吗?
如果没有区别?
关于c ++部分
常量指针和引用之间有什么区别?
它们看起来像是做同一件事的另一种方式,如果引用概念已经以常量指针的形式存在,为什么还要将引用概念添加到c ++?
关于Java部分
有没有一种方法(在Java中)模拟指向c ++常量值的指针的相同行为?基本上有什么方法可以使常量值不变?
更类似于const Shape* s = new Shape;
编辑:我发现至少有一个引入参考概念的原因
当我们定义一个拷贝构造函数时,我们需要将该对象作为参数而没有引用,我们将得到一个无限循环
C ++:
class Shape{
public:
int member = 3;
};
Shape s1;
Shape s2;
Shape* const cp_var_1 = &s1;
cp_var_1->member = 5; // valid
cp_var_1 = &s2; //not valid
Shape& ref_var_2 = s1;
ref_var_2.member = 6; // valid - s1 changed as well
// cant change ref_var_2 to reference other variable (like s2)
ref_var_2 = s2;
// assignment operator called - s1 and s2 content are the same
// but ref_var_2 still reference s1
Java:
class Shape{
public int member = 3;
}
Shape s1 = new Shape();
Shape s2 = new Shape();
final Shape final_var_3 = s1;
final_var_3.member = 7; // valid
final_var_3 = s2; // not valid
答案 0 :(得分:0)
是的,您是完全正确的:在final var_3 = s1;
中,final
阻止您使var_3
引用其他任何内容,但是您可以取消引用变量并执行您想做的任何事情您在其中找到的内容:var_3.member = 7;
是有效的(点是取消引用运算符)。
请注意,java中的final
关键字用于不同的目的。您可以将类标记为final,这意味着它们无法扩展。 (class Foo extends SomeClassMarkedFinal {}
无法编译)。 final
也可以应用于方法:在这种情况下,这意味着任何子类都不能覆盖此方法。尽管英语名称final
似乎可以很好地说明所有这些行为,但变量声明中使用的final
和方法和类中使用的final
却完全不同无关。
许多Java类型(例如java.lang.String
,java.lang.Integer
等)被称为“不可变的”:这些对象绝对无法更改它们的任何内容。 java的字符串是对象(不是ersatz char数组),您无法访问基础的char数组,没有clear()
或setChar()
方法,等等:因此,string类型的最终变量是完全恒定的
Java在当前意义上不(目前)不提供任何将类型标记为“常量”的方式,将其添加为概念可能没有多大意义。例如,在Java中,代表文件路径的java.io.File
是不可变的:它绝对没有方法来改变其任何状态。
但是,它是不变的吗?是“恒定”吗?如果我运行file.delete(),即使对象本身(只有一个字段,类型为string,包含文件路径),也没有任何改变,但是我可以肯定地观察到更改。
答案 1 :(得分:-1)
Java中的final
关键字确实具有(基本上)与c ++中的引用或常量指针相同的效果,但是c ++中的const
最终变得更加通用和强大。
如果您有一个指向const
对象的指针或引用,则该对象本身应被视为不可变的。例如,如果函数使用const引用对象,则可以假设不会修改对象,从而可以安全地传递对象。而且,如果我编写一个const
成员函数,那我保证该成员函数不会修改基础对象。
在函数参数(尤其是通过引用或指针传递的参数)中添加const
可使程序员更轻松地推理代码。他们知道可以期望这些投入保持不变。跟踪错误时,这是一个巨大的好处,并且可以更容易地为正确使用const
的外部库推断接口。
最后,与Java不同,允许(并鼓励)使用C ++中的按引用获取值的函数假定您传递的引用不为null。很好如果您编写代码以使引用永远不会为null,则代码将变得更简单,更简洁,更快捷(因为您不必进行null检查)。