В учебнике по программированию на Java для C ++ говорится, что (выделение - мое):
Ключевое слово final примерно эквивалентно const в C ++
Что значит «грубо» в этом контексте? Разве они точно так же?
Каковы различия, если таковые имеются?
В C ++ маркировка членской функции const
означает, что она может быть вызвана для const
экземпляров. У Java нет эквивалента этому. Например:
class Foo {
public:
void bar();
void foo() const;
};
void test(const Foo& i) {
i.foo(); //fine
i.bar(); //error
}
Значения могут быть назначены, один раз, позже только в Java, например:
public class Foo {
void bar() {
final int a;
a = 10;
}
}
допустимо в 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.
}
}
И в Java, и в C ++ переменные-члены могут быть final
/ const
соответственно. Им должно быть присвоено значение к моменту завершения создания экземпляра класса.
В Java они должны быть установлены до завершения конструктора, это может быть достигнуто одним из двух способов:
public class Foo {
private final int a;
private final int b = 11;
public Foo() {
a = 10;
}
}
В C ++ вам нужно будет использовать списки инициализации, чтобы дать const
членам значение:
class Foo {
const int a;
public:
Foo() : a(10) {
// Assignment here with = would not be legal
}
};
В Java финал может использоваться, чтобы пометить вещи как не подлежащие переопределению. C ++ (до C ++ 11) этого не делает. Например:
public class Bar {
public final void foo() {
}
}
public class Error extends Bar {
// Error in java, can't override
public void foo() {
}
}
Но в C ++:
class Bar {
public:
virtual void foo() const {
}
};
class Error: public Bar {
public:
// Fine in C++
virtual void foo() const {
}
};
это хорошо, потому что семантика маркировки функции-члена 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() {
}
}
Теперь можно точно написать на C ++ 11 как:
class Bar {
public:
virtual void foo() final;
};
class Error : public Bar {
public:
virtual void foo() final;
};
Мне пришлось скомпилировать этот пример с предварительной версией G ++ 4.7. Обратите внимание, что это не заменяет const
в этом случае, а скорее дополняет его, предоставляя Java-подобное поведение, которое не было видно с наиболее близким эквивалентным ключевым словом C ++. Поэтому, если вы хотите, чтобы функция-член была и тем, final
и другим, const
вы должны сделать:
class Bar {
public:
virtual void foo() const final;
};
(Порядок const
и final
здесь обязателен).
Ранее не было прямого эквивалента const
функций-членов, хотя создание функций non- virtual
было бы потенциальным вариантом, хотя и не вызывало ошибки во время компиляции.
Аналогично Java:
public final class Bar {
}
public class Error extends Bar {
}
делается в C ++ 11:
class Bar final {
};
class Error : public Bar {
};
(Ранее private
конструкторы были, вероятно, ближе всего к этому в C ++)
Интересно, что для обеспечения обратной совместимости с кодом до C ++ 11 final
это не ключевое слово обычным способом. (Возьмем тривиальный, легальный пример C ++ 98, struct final;
чтобы понять, почему создание ключевого слова может привести к поломке кода)
final int a; a = 10; a = 11;
это не так (это является цельюfinal
модификатора переменной). Кроме того, конечные члены класса могут быть установлены только во время объявления или один раз в конструкторе. ,final
декоратор-член для этой конкретной цели. VC ++ 2005, 2008 и 2010 уже реализовали это, используяsealed
вместо этого контекстное ключевое словоfinal
.В Java последнее ключевое слово может использоваться для четырех вещей:
Одна важная вещь: переменная конечного члена Java должна быть установлена ровно один раз! Например, в конструкторе, объявлении поля или инициализаторе. (Но вы не можете установить конечную переменную-член в методе).
Другое последствие создания переменной-члена final относится к модели памяти, что важно, если вы работаете в многопоточной среде.
источник
const
Объект может вызывать толькоconst
методы, и как правило , считается неизменны.final
Объект не может быть установлен на новый объект, но это не является неизменным - есть ничто не мешает кому - то из вызова любыхset
методов.У Java нет встроенного способа объявления объектов неизменными; Вы должны сами проектировать класс как неизменный.
Когда переменная имеет примитивный тип,
final
/const
работают так же.источник
Java final эквивалентен C ++ const для типов примитивных значений.
В ссылочных типах Java последнее ключевое слово эквивалентно константному указателю ... т.е.
источник
У вас уже есть несколько хороших ответов, но один момент, который, кажется, стоит добавить:
const
в C ++ обычно используется для предотвращения изменения состояния других частей программы. Как уже указывалось,final
в Java это не может быть сделано (за исключением примитивов) - оно просто предотвращает изменение ссылки на другой объект. Но если вы используетеCollection
, вы можете предотвратить изменения ваших объектов с помощью статического методаЭто возвращает
Collection
ссылку, которая дает доступ на чтение к элементам, но выдает исключение, если попытки изменения сделаны, делая это немного какconst
в C ++источник
Java
final
работает только с примитивными типами и ссылками, а не с самими экземплярами объектов, где ключевое слово const работает с чем угодно.Сравнение
const list<int> melist;
сfinal List<Integer> melist;
первым делает невозможным изменение списка, в то время как последний только мешает вам назначить новый списокmelist
.источник
Помимо наличия определенных и тонких многопоточных свойств , объявленные переменные
final
не нужно инициализировать при объявлении!т.е. это действительно в Java:
Это не будет действительным, если написано с C ++
const
.источник
Согласно википедии :
источник
Я предполагаю, что это говорит "грубо", потому что значение
const
в C ++ усложняется, когда вы говорите об указателях, то есть постоянных указателях по сравнению с указателями на постоянные объекты. Поскольку в Java нет «явных» указателей,final
таких проблем нет.источник
Позвольте мне объяснить, что я понял, на примере оператора switch / case.
Значения в каждом операторе case должны быть значениями констант времени компиляции того же типа данных, что и значение параметра.
объявите что-то вроде ниже (или в вашем методе как локальные экземпляры, или в вашем классе как статическую переменную (затем добавьте статическую переменную), или переменную экземпляра.
и
Этот код не будет компилироваться, если
color1
это переменная класса / экземпляра, а не локальная переменная. Это скомпилируется, еслиcolor1
определено как static final (тогда оно становится статической final final).Когда он не скомпилируется, вы получите следующую ошибку
источник
Ключевое слово «const» означает, что ваша переменная сохраняется в ПЗУ (с микропроцессором). на компьютере ваша переменная сохраняется в области ОЗУ для кода сборки (ОЗУ только для чтения). это означает, что ваша переменная отсутствует в ОЗУ с возможностью записи: статическая память, стековая память и кучная память.
Ключевое слово "final" означает, что ваша переменная сохраняется в ОЗУ с возможностью записи, но вы замечаете, что ваша переменная изменяется только один раз.
Я думаю, что «const» плохо работает, поэтому Java его не использует.
источник