Win*_*Win 144 c++ java final const
该Java进行C++程序员教程说,(大亮点是我自己的):
关键字final 大致 相当于C++中的const
在这种情况下,"大致"意味着什么?它们不完全一样吗?
有什么区别,如果有的话?
Fle*_*exo 185
在C++中,标记成员函数const意味着可以在const实例上调用它.Java没有与之相当的东西.例如:
class Foo {
public:
void bar();
void foo() const;
};
void test(const Foo& i) {
i.foo(); //fine
i.bar(); //error
}
Run Code Online (Sandbox Code Playgroud)
可以在Java中稍后分配值,例如:
public class Foo {
void bar() {
final int a;
a = 10;
}
}
Run Code Online (Sandbox Code Playgroud)
在Java中是合法的,但不是C++而是:
public class Foo {
void bar() {
final int a;
a = 10;
a = 11; // Not legal, even in Java: a has already been assigned a value.
}
}
Run Code Online (Sandbox Code Playgroud)
在Java和C++中,成员变量可以分别为final/ const.这些需要在类的实例构建完成时给出一个值.
在Java中,必须在构造函数完成之前设置它们,这可以通过以下两种方式之一来实现:
public class Foo {
private final int a;
private final int b = 11;
public Foo() {
a = 10;
}
}
Run Code Online (Sandbox Code Playgroud)
在C++中,您需要使用初始化列表为const成员提供值:
class Foo {
const int a;
public:
Foo() : a(10) {
// Assignment here with = would not be legal
}
};
Run Code Online (Sandbox Code Playgroud)
在Java中,final可用于将事物标记为不可覆盖.C++(pre-C++ 11)不会这样做.例如:
public class Bar {
public final void foo() {
}
}
public class Error extends Bar {
// Error in java, can't override
public void foo() {
}
}
Run Code Online (Sandbox Code Playgroud)
但在C++中:
class Bar {
public:
virtual void foo() const {
}
};
class Error: public Bar {
public:
// Fine in C++
virtual void foo() const {
}
};
Run Code Online (Sandbox Code Playgroud)
这很好,因为标记成员函数的语义const是不同的.(您也可以通过仅使用其中一个成员函数来重载const.(另请注意,C++ 11允许将成员函数标记为final,请参阅C++ 11更新部分)
事实上,C++ 11允许您将类和成员函数标记为final与Java中的相同特性具有相同的语义,例如在Java中:
public class Bar {
public final void foo() {
}
}
public class Error extends Bar {
// Error in java, can't override
public void foo() {
}
}
Run Code Online (Sandbox Code Playgroud)
现在可以用C++ 11编写为:
class Bar {
public:
virtual void foo() final;
};
class Error : public Bar {
public:
virtual void foo() final;
};
Run Code Online (Sandbox Code Playgroud)
我必须使用预发布的G ++ 4.7编译这个例子.请注意,const在这种情况下,这不会替换,而是对其进行扩充,从而提供类似Java的行为,而这种行为与最接近的等效C++关键字一样.所以,如果你想要一个成员函数final,const你会这样做:
class Bar {
public:
virtual void foo() const final;
};
Run Code Online (Sandbox Code Playgroud)
(此处的顺序const和final此处是必需的).
以前没有const成员函数的直接等价,尽管使函数非virtual可能是一个潜在的选项,尽管在编译时不会导致错误.
同样是Java:
public final class Bar {
}
public class Error extends Bar {
}
Run Code Online (Sandbox Code Playgroud)
变成了C++ 11:
class Bar final {
};
class Error : public Bar {
};
Run Code Online (Sandbox Code Playgroud)
(以前的private构造函数可能是你在C++中最接近的构造函数)
有趣的是,为了保持与前C++ 11代码的向后兼容性,代码final 不是通常的关键字.(以简单,合法的C++ 98为例struct final;,了解为什么将其作为关键字会破坏代码)
Ral*_*lph 30
在Java中,final关键字可用于四件事:
一个重要的事情是:Java最终成员变量必须设置一次!例如,在构造函数,字段声明或初始化器中.(但是你不能在方法中设置最终的成员变量).
使成员变量最终的另一个结果与内存模型有关,如果您在线程环境中工作,这很重要.
Blu*_*eft 25
一个const对象只能调用const方法,并且通常被认为是不可变的.
const Person* person = myself;
person = otherPerson; //Valid... unless we declared it const Person* const!
person->setAge(20); //Invalid, assuming setAge isn't a const method (it shouldn't be)
Run Code Online (Sandbox Code Playgroud)
一个final对象不能被设置为一个新的对象,但它不是一成不变的-没有什么从调用任何停止的人set的方法.
final Person person = myself;
person = otherPerson; //Invalid
person.setAge(20); //Valid!
Run Code Online (Sandbox Code Playgroud)
Java没有固有的方法来声明对象不可变; 你需要将类设计为不可变的.
当变量是基本类型时,final/ const工作相同.
const int a = 10; //C++
final int a = 10; //Java
a = 11; //Invalid in both languages
Run Code Online (Sandbox Code Playgroud)
Jam*_*hek 12
Java final相当于原始值类型的C++ const.
对于Java引用类型,final关键字等效于const指针...即
//java
final int finalInt = 5;
final MyObject finalReference = new MyObject();
//C++
const int constInt = 5;
MyObject * const constPointer = new MyObject();
Run Code Online (Sandbox Code Playgroud)
你已经有了一些很好的答案,但有一点似乎值得补充:const在C++中常用来防止程序的其他部分改变对象的状态.正如已经指出的那样,final在java中不能这样做(除了原语) - 它只是阻止引用被改为不同的对象.但是,如果您使用的是a Collection,则可以使用静态方法阻止对对象的更改
Collection.unmodifiableCollection( myCollection )
Run Code Online (Sandbox Code Playgroud)
这将返回一个Collection引用,该引用提供对元素的读访问,但如果尝试修改则抛出异常,使其有点像const在C++中
Java final仅适用于原始类型和引用,而不适用于const关键字适用于任何事物的对象实例本身.
比较const list<int> melist;与final List<Integer> melist;第一使其无法修改列表,而后者只阻止你分配一个新的列表melist.