Для определения второго const
версия функции, это безопасно делать? Похоже, что это будет бесконечная рекурсия, как я хочу вернуться const
но другая функция, которую я хочу назвать, неконстантна.
Это работает с g ++, но я беспокоюсь, что это небезопасно.
#include <iostream>
using namespace std;
class test {
public:
int* doSomething(int a) {
int* someInt = new int(a);
return someInt;
}
const int* doSomething(int a) const {
return doSomething(a);
}
};
int main() {
test a;
cout << *a.doSomething(12345) << endl;
return 1;
}
Не совсем: как отметил @Pete Becker в комментариях, если бы вы назвали const
версия, что будут рекурсия:
class test {
public:
int* doSomething(int a) {
int* someInt = new int;
*someInt = a;
return someInt;
}
const int* doSomething(int a) const {
return doSomething(a);
}
};
int main() {
const test a;
// You're not in for a good time:
a.doSomething(12345);
return 1;
}
При предоставлении const
и неconst
версии функции, которая требует дублирования кода, лучше всего реализовать const
версия, то есть неconst
Версия называют это определенным образом.
Скотт Майерс Эффективный C ++ — Третье издание:
когда
const
и неconst
Функции-члены имеют практически идентичную реализацию, дублирования кода можно избежать, еслиconst
версия позвонитьconst
версия
Скотт Майерс продолжает предоставлять безопасные средства для этого:
const int* doSomething(int a) const
{
int* someInt = new int;
*someInt = a;
return someInt;
}
int* doSomething(int a)
{
return const_cast<int*>(static_cast<const Test&>(*this).doSomething());
}
В неconst
версия, есть два броска: static_cast
в основном получается this
в const this
, где const_cast
отбрасывает const
-возвратность Это безопасно сделать, потому что для вызоваconst
версия, вы должны былиconst this
,
Однако, если вы просто предоставляете доступ к члену, его легко и просто прочитать, чтобы иметь следующее:
class TestAccess;
class Test
{
TestAccess& t;
public:
const TestAccess& getA() const { return t; }
TestAcess& getA() { return t; }
};
В этом случае компилятор всегда выбирает неконстантную версию функции, даже не вызывает константную.
В противном случае компилятор не скомпилируется, вы нарушаете целостность.
Например, я быстро изменил код:
#include <iostream>
using namespace std;
class test {
public:
int* doSomething(int a) {
int* someInt = new int;
*someInt = a;
return someInt;
}
int ax = 10;
void somethingElse(int i)
{
ax = i;
}
const int* doSomething(int a) const {
somethingElse(a);
return 0;
}
};
int main() {
test a;
cout << *a.doSomething(12345) << endl;
return 1;
}
Этот пример не компилируется, потому что вы вызываете функцию const внутри области действия const. Компилятор не позволит вам сделать это.
Теперь я знаю, что это тест, но, выполняя этот путь, вы никогда не выйдете из рекурсии, он будет зацикливаться вечно, а также вы теряете память при каждом вызове, выделяя кучу, эти две вещи вместе могут привести к катастрофе.