2013-05-23 2 views
2

У меня есть две версии кода на C++. Одна дать проблему и другой не делает:ошибка с константным элементом и конструктором по умолчанию

/* 
* This compiles fine 
*/ 
class base { 
    private: 
     const char c; 
    }; 

int main() { 
    base b(); // compiles fine 
} 

/* * Это дает ошибку компиляции */

class base { 
    private: 
     const char c; 
    }; 

int main() { 
    base b; // error: structure 'b' with uninitialized const members 

} 

Примечание разница 'база Ь()' и 'база Ь'. Я думал, что оба вызову вызовет конструктор по умолчанию, и поскольку класс имеет поле const, программа не сможет скомпилировать. Пожалуйста, помогите объяснить это.

+0

Возможный дубликат [почему конструктор по умолчанию отсутствует для класса, содержащего элементы данных const) (http://stackoverflow.com/questions/16706674/why-default-constructor-is-not-present-for- a-class-contains-const-data-members) – juanchopanza

+0

Вы еще одна жертва «наиболее неприятного анализа» C++ (вы можете использовать его в Google): 'base b();' ** ** ** не анализируется как определение переменной компилятором, но как объявление _функции_ - так же, как 'int f();' или 'void g();'. (Правило большого пальца: все, что компилятор _can_ интерпретирует как объявление функции, это _will_.) –

ответ

3

Это происходит потому, что первая версия не создает объект типа base, а объявляет функцию называется b, который не принимает аргументов и возвращает объект типа base:

base b; // Declares an object b of type base 
base b(); // Declares a FUNCTION called b that takes no argument an returns a base 

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

int main() { 
    base b(); // DECLARES function b() 
    b(); // INVOKES function b() 
} 

base b() // DEFINITION of function b() 
{ 
    base c; 
    // ... 
    return c; 
} 

Теперь работать main() не даст вам проблем больше, но base c; внутри функции b() будет. Точно как base b; в вашем оригинальном примере. Зачем?

Хорошо, потому что в общем случае элементы данных, тип которых const -qualified, должны быть инициализированы, как только вы создадите объект (точно так же, как элементы данных ссылочного типа). Способ гарантировать это в целом состоит в том, чтобы инициализировать эти элементы данных в constructor's initialization list.

Это, например, будет компилировать:

class base { 
public: 
    base() : c('x') { } 
private: 
    const char c; 
}; 

int main() { 
    base b; 
} 
+0

Спасибо Энди. Вы объяснили это хорошо. – ArvindDotiyal

+0

@ user2414310: Рад, что это помогло :) Если это ответит на ваш вопрос, пожалуйста, подумайте о том, чтобы отметить ответ как принятый (или любой другой ответ, предоставленный другими пользователями, который вы можете предпочесть). –

1

Const символ с; Должен быть определен при объявлении. const char c = 'a'; например,

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