Недопустимая инициализация члена

Я использую этот довольно простой класс без использования какого-либо наследования.

class A
{
  int a;
  int b;

public:
 A(int x, int y) { a = x; b = y;}
 A() :A(0,0){};
 ~A(){};
} ;

int main ()
{
  A a1, a2(5, 7) ;
}

Я получаю эту ошибку.

ошибка C2614: «A»: недопустимая инициализация члена: «A» не является базой или членом

На SO есть похожие вопросы, но они относятся к наследованию. Может кто-нибудь объяснить причину и что об этом говорит стандарт?

ИЗМЕНИТЬ:

Было бы лучше, если бы кто-нибудь подробнее рассказал о конструкторе пересылки и этой функции в С++ 11.


person Coding Mash    schedule 20.10.2012    source источник
comment
Это отлично компилируется для меня, но не в gcc   -  person 0x499602D2    schedule 20.10.2012
comment
похоже, вы используете Visual Studio 2010 (или более раннюю версию), он даже не работает в VS2010. Я слышал, что в SP1 и VS2012 добавлено больше возможностей C++11, но я не уверен.   -  person Aniket Inge    schedule 20.10.2012
comment
См. n1986.   -  person Mankarse    schedule 20.10.2012
comment
Возможный дубликат С++ 11, вызывающий конструктор из конструктора того же класса тип   -  person Florian Castellane    schedule 21.07.2016


Ответы (5)


Если вы можете использовать C++11, вы можете инициализировать A() из A(int, int). Это невозможно в C++03, где вам нужно написать два отдельных конструктора.

Если вы хотите, чтобы ваш код работал на C++03, у вас есть два варианта:

  • Создайте функцию init(int, int) и вызовите ее из каждого из ваших конструкторов. Это хороший выбор, если ваш конструктор выполняет много работы.
  • Дублированное поведение в обоих конструкторах. Это хороший выбор, когда все, что вы делаете, — это инициализация элементов.

Вы также можете вызвать базовый конструктор из конструктора дочернего класса. Например, если у вас есть

class A {
    A(int, int);
};
class B : public A {
    B(int, int);
};

Вы могли бы написать

B::B(int x, int y) : A(x,y) {}

Именно это имеет в виду ваш компилятор, когда говорит, что A is not a base ожидает такой ситуации.

Все они совместимы с C++03.

Вы также можете обновить свой компилятор, чтобы он поддерживал функции C++11. Я бы не рекомендовал это, если вы работаете в Linux и хотите, чтобы ваш проект компилировался в Windows, потому что компиляторы Windows не реализуют все функции C++, которые делают компиляторы Linux (если вы не платите за хороший компилятор).

person alestanis    schedule 20.10.2012

это из-за вашей проблемы с конструктором в:

Судя по вашему сообщению об ошибке, я предполагаю, что вы используете Visual Studio (вероятно, 2010), и я согласен, что это не работает в VS2010.

A:A(0,0){ }

Исправление для VS 2010 и его предшественников: A():a(0),b(0){}

person Aniket Inge    schedule 20.10.2012
comment
теперь это допустимо в С++ 11, это называется цепочкой конструкторов. - person Stephane Rolland; 20.10.2012

Вы не можете сделать это так A() :A(0,0){}; этот способ используется для инициализации базовых членов класса.

A(){a=0;b=0;};

или если вы хотите определить private: void set(int x, int y); и использовать его в конструкторах.

person Alexander Nekrasov    schedule 20.10.2012

A() :A(0,0){}; называется цепочкой конструкторов.

Вы должны убедиться, что ваш компилятор принимает С++ 11. Цепочка конструкторов допустима только в C++11. Раньше это было недоступно.

Какой компилятор вы используете?

person Stephane Rolland    schedule 20.10.2012
comment
возможно, Microsoft еще не реализовала это. Только часть C++11 поддерживается VS2010. - person Stephane Rolland; 20.10.2012

Вы пытаетесь использовать конструктор делегирования, который представляет собой языковую функцию, представленную только в C++11 и еще не реализованную во всех компиляторах.

person Mankarse    schedule 20.10.2012