В Java есть ключевое слово final
и в C++ есть похожее ключевое слово const
. В Java со всеми объектами работают только через ссылки на них, в C++ это является лишь одной из возможностей. В Java final
ссылка на объект означает лишь то, что нельзя менять саму ссылку, но если объект мутабельный, можно менять его состояние. По наивности я думал, что в C++ всё примерно так же, но оказалось, что совсем не так.
Для начала простой пример на Java
public class MainClass {
private static void foo(final StringBuilder stringBuilder) {
stringBuilder.append("#foo()");
System.out.println(stringBuilder);
}
public static void main(String[] args) {
foo(new StringBuilder("Hello from MainClass"));
}
}
Этот код изменяет содержимое stringBuilder
и после этого печатает Hello from MainClass#foo()
Теперь перейдём к коду на C++
#include <iostream>
#include <string>
void foo(std::string& str) {
str.append("foo()");
std::cout << str << std::endl;
}
int main() {
std::string str{"Hello from "};
foo(str);
return 0;
}
В этом коде функция foo()
так же получает ссылку на стринговый объект, изменяет содержимое этого объекта не меняя саму ссылку и печатает результат: Hello from foo()
. Но стоит добавить ключевое слово const
перед объявлением этой ссылки в аргументах функции foo()
и код перестаёт компилироваться из-за неожиданного отсутствия append()
.
Среди Java разработчиков попадаются и бывшие сишники. Обычно их можно обнаружить по некоторым привычкам из C/C++. Например по 5 == n
, что для Java совершенно бесполезно, поскольку int
не кастится в boolean
и соответственно ошибочно написанное if (n = 5)
приведёт к ошибке компиляции, как и if (5 = n)
в C/C++. Так вот в некоторых компаниях Java разработчиков заставляют (например через maven-checkstyle-plugin) объявлять все аргументы публичных методов как final
, что совершенно глупо и только раздражает. Сейчас у меня появилось предположение, что это пришло от покусанных C++ бывших сишников.
Так от какого же языка травма?