2014-02-16 4 views
2

У меня есть этот простой код: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(); 

EDIT: Как заявил @ditskowitch и @ N.m. - Я полагаю, что ошибка - это не ошибка. Для этого явный конструктор не нужен. Это может быть teoreticaly проблема только в том случае в зависимости от кода ожидает, что ссылка, возвращенное функцией() баллов в какой-то адрес, как показано на @Rory Yorke

+0

Позвольте мне лучше понять, чего вы хотите. Вы хотите, чтобы 'B & a = function()' выполнялся неудачно, но 'B b = function()' преуспел, правильно? –

+0

@ н.м .: да, вы правы. – user3123061

+0

Это вряд ли возможно. –

ответ

2

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

+0

Но это тоже плохо. Итак, вы говорите, компилятор создает временную B. И тогда ссылка на это временное происходит позже, но в это время этот временной B больше не существует! – user3123061

+1

@ user3123061: это неправда. В этом случае продление срока временного продлевается, см., Например, [этот вопрос] (http://stackoverflow.com/questions/2784262/does-a-const-reference-prolong-the-life-of-a-temporary). –

+0

@ н.м. Это хорошая новость для меня. :-) Спасибо за эту ссылку! – user3123061

1

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

испачкать "B от A" конструктору explicit:

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

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

 Смежные вопросы

  • Нет связанных вопросов^_^