2016-08-18 4 views
-5

Почему BASE *base_0 = new BASE(); //error? выделяет память при определении класса?C++ 11 class initialize error

class BASE { 

public: 
    int *i = new int(5);        
    BASE *base_0 = new BASE();  
    static const BASE base_1;  
    static BASE base_2;    
    ~BASE() { 
    cout << "~"; 
    } 

}; 
+4

um what? не создаст 'BASE' создать другую' BASE' через 'new' и, следовательно, навсегда создать другую' BASE' и другую 'BASE'? что здесь используется? – vu1p3n0x

+1

Можете ли вы предоставить ошибку, полученную от компилятора? – JVApen

+1

синтезированный метод 'constexpr BASE :: BASE()' сначала требуется здесь | – QuantumEnergy

ответ

3

Различные компиляторы дают разные ошибки:

struct S { 
    S* s = new S(); 
}; 

под правой версии GCC производит:

prog.cpp:2:15: error: constructor required before non-static data member for 'S::s' has been parsed 
    S* s = new S(); 
      ^

http://ideone.com/8TU5Th

Даже если вы на самом деле не вызывая new в данный момент , компилятор должен разобрать звонок new. Поскольку вы не поставляете по умолчанию ctor, он должен синтезировать один, но он не может этого сделать, потому что этот член ссылается на new, который ссылается на ctor по умолчанию, поэтому пока этот оператор не будет полностью обработан, он не может знать, как сгенерировать т е р.

Кроме того, вы говорите, что «я не создаю какой-либо объект БАЗЫ» в комментариях на другой ответ, но в самом деле, вы делаете:

static const BASE base_1;  
static BASE base_2;    

оба этих заявлений потребуется программа для default-initialize экземпляр BASE при запуске, и первое, что этот экземпляр BASE будет делать, это выделить динамический экземпляр BASE и вызвать его конструктор, который будет ...

1

Вы упускаете конструктор и он пытается заполнить новую базу() перед созданием конструктора по умолчанию. Это ошибка constexpr BASE::BASE(), которую вы получили. Добавление конструктора BASE::BASE() в любом месте вашего класса должно устранить проблему.

Для инициализации указателей вы можете также сделать это в конструкторе.

class BASE 
{ 

public: 
    BASE() 
    { 
    std::cout << "c"; 
    i = new int(5); 
    base_0 = new BASE(); 
    } 
    ~BASE() 
    { 
    std::cout << "~"; 
    } 

    int *i;        
    BASE *base_0; 
    static const BASE base_1;  
    static BASE base_2;     
}; 

Хотя использование для этого неизвестно мне. При создании нового BASE он также компилирует конструктор. Это происходит каждый раз, когда создается новый класс, поэтому, когда вы создаете новый класс BASE внутри конструктора BASE, вы собираетесь создавать новые классы BASE, пока не исчерпаете память.

По существу это вилка.

+0

спасибо за anwser, но я не создаю никакого объекта BASE, определение не должно выделять память. Я просто определяю класс, подобный этому, и компилирую ошибку: синтезированный метод «constexpr BASE :: BASE()» сначала требуется здесь, я обнаружил, что если я перезаписываю BASE() {}, нет ошибок, конечно, если я использую объект этого класса, то, что вы сказали, может случиться, но я просто хочу знать, почему я просто это определяю, компиляция также имеет ошибку? Спасибо! – QuantumEnergy

+0

Подумайте об этом: «Синтезированный метод» - это конструктор «constexpr BASE :: BASE()». Компилятор смотрит на строку 'BASE * base_0 = new BASE()' и пытается найти конструктор 'BASE :: BASE()' перед его синтезом. – mstehula

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