Компилятор C ++ может молча принять неверное преобразование и внести непредсказуемые ошибки

У меня есть этот простой код:

class A {
public:
int m;
};

class B : public A {
public:
B(const B& b) { /*...*/ }
B(const A& a) { /*...*/ }
int n;
};

const A& function()
{
static A a;
return a;
}

int main()
{
const B& a = function();
const int x = a.n; // !!!!! Error: probably reads some random mess

/* ... */

B b2 = function();

/* ... */

return 0;
}

В этом коде я демонстрирую, что может произойти, если вы по ошибке напишите const B& a = function() вместо const A& a = function(), И компилятор не ловит эту ошибку! Чтобы отловить эту ошибку во время компиляции, конструктор B(const A& a) должно быть explicit, Но разметка конструктора explicit отключает способность делать B b2 = function(); — это должно быть написано более уродливо: B b2(function());

Вопрос: Существует ли какой-нибудь способ отловить этот тип ошибки во время компиляции, сохраняя возможность написать это?

B b2 = function();

РЕДАКТИРОВАТЬ: Как утверждают @ditskowitch и @ n.m. То, что я предполагаю быть ошибкой, не является ошибкой. Для этого явный конструктор не нужен. Теоретически это может быть проблемой, только если зависимый код ожидает, что ссылка, возвращаемая функцией (), указывает на какой-то адрес, как показывал @Rory Yorke

2

Решение

Компилятор ведет себя правильно: так как ваш B class имеет конструктор, принимающий const A& — вы на самом деле делаете это B может быть должным образом создан из экземпляра A, Так что не должно быть никакого «случайного беспорядка» в x, но значение, которое конструктор присваивает nпри построении из экземпляра A

2

Другие решения

Вопрос: существует ли какой-нибудь способ отловить этот тип ошибки во время компиляции, сохраняя возможность написать это?

Маркировка вашего конструктора «B из A» как explicit:

explicit B(const A& a) { /*...*/ }

не позволит компилятору использовать его для автоматического преобразования. Увидеть этот вопрос для дополнительной информации.

1

По вопросам рекламы ammmcru@yandex.ru
Adblock
detector