Ошибка компилятора c2614

description title ms.date f1_keywords helpviewer_keywords ms.assetid

Learn more about: Compiler Error C2614

Compiler Error C2614

11/04/2016

C2614

C2614

a550c1d5-8718-4e17-a888-b2619e00fe11

Compiler Error C2614

‘class1’ : illegal member initialization: ‘class2’ is not a base or member

Only member or base classes can appear in the initialization list for a class or structure.

Example

The following sample generates C2614.

// C2614.cpp
// compile with: /c
struct A {
   int i;
   A( int ia ) : B( i ) {};   // C2614 B is not a member of A
};

struct A2 {
   int B;
   int i;
   A2( int ia ) : B( i ) {};   // OK
};

I am getting the following error in C++:

error C2614: ‘ChildClass’ : illegal member initialization: ‘var1’ is
not a base or member

Class Base 
{
    protected:
    int var1;
public:
    Base()
    {
        var1=0;
    }
}


class Child : public Base
{
    int chld;
    public: 
    Child() : var1(0)
    {
        chld=1;
    }
}

I feel what I have done is as per OO protocol.
Here var1 is a data member of Base class with protected as the access specifier. So It can be inherited and it would become private in child.

Don’t understand why am I getting the error?

CinCout's user avatar

CinCout

9,45411 gold badges49 silver badges67 bronze badges

asked Apr 13, 2012 at 9:31

codeLover's user avatar

2

It doesn’t work for the exact reason the error message provides you: you can only use initializer lists with direct members or base classes.

In your case, you don’t even need to initialize var1, since Base::Base() will be called by Child‘s constructor, which will set var1 to 0.

If you want a different value, you’ll have to overload Base constructor and call it explicitly:

class Base 
{
protected:
     int var1;
public:
     Base() : var1(0)
     {
     }
     Base(int x) : var1(x)
     {
     }
};

class Child:public Base
{
    int chld;
public: 
    Child(): Base(42) , chld(1)
    {
    }
};

answered Apr 13, 2012 at 9:34

Luchian Grigore's user avatar

Luchian GrigoreLuchian Grigore

252k64 gold badges457 silver badges621 bronze badges

1

You can’t initialize a member of a base class, only of the current class. Use a parameterized constructor in the base class.

Class Base 
{
  protected:
     int var1;
     Base( int var ) : var1(var)
     {}
  public:
     Base()
     {
        var1=0;
     }
};

class Child:public Base
{
      int chld;
   public: 
      Child():Base(0)
      {
         chld=1;
      }
};

answered Apr 13, 2012 at 9:34

sharptooth's user avatar

sharptoothsharptooth

167k100 gold badges510 silver badges969 bronze badges

0

  • Remove From My Forums
  • Question

  • hi i keep getting an error for health, strength, and speed i know what the problem is but i’m not sure how to fix it

    #pragma once
    #include<iostream>
    #include<stdio.h>
    using namespace std;

    class characters
    {
        float health;
        int strength;
        int speed;
    public:
        virtual    void print()
        {
        }
    };
    class fighter1:public characters
    {
        fighter1(float h,int st, int sp):health(h),strength(st),speed(sp)
        {
            h = 10;
            st = 5;
            sp = 5;   
        }

Answers

  • The variables are private and therefore not accessible in the class fighter1.  You need to make them protected or public.  You should also provide a constructor in the class characters that initialize these variables, pretty much like the one
    you are trying to write for fighter1.


    Jose R. MCP

    • Proposed as answer by

      Tuesday, November 22, 2011 3:46 AM

    • Marked as answer by
      Helen Zhao
      Thursday, November 24, 2011 5:44 AM

  • Hi Gregar0,

    I agree with webJose. You received this error because these variables are private in class characters.

    Default access of members in a class is private. And class members declared as private can be used only by member functions and friends(classes and functions) of the class. Class fighter1 is a derived class of class characters, so it is illegal to initialize
    health, strength, and speed.

    If you really need access to these members, please declare them as public or protected.
    We can’t use initializer list in class fighter1 because health, strength, and speed are members of characters, not members of it. You can create a constructor for fighter1 like this:

    fighter1(float h,int st, int sp)
    {
           health=h;
           strength=st;
           speed=sp;
    }
    
    

    Or you can do it like this is you have a constructor in base class:

    fighter1(float h,int st, int sp):characters(…..//argument list)
    {
            health=h;
            strength=st;
            speed=sp;
    }
    
    

    By the way, what is your purpose of the codes in the body of fighter1’s constructor? It seems weird because it makes no sense to the variables.

    I hope this reply is helpful to you.
    Best regards,


    Helen Zhao [MSFT]
    MSDN Community Support | Feedback to us

    • Proposed as answer by
      Helen Zhao
      Tuesday, November 22, 2011 3:45 AM
    • Marked as answer by
      Helen Zhao
      Thursday, November 24, 2011 5:44 AM


Конструктор. Ошибка C2614

От:

zfima

 
Дата:  28.09.09 08:51
Оценка:

:)

Здрасте.
Коротко:
почему так можно

class area_cl{
public:
    int height;
    int width;
};

class cilinder: public area_cl{
public:cilinder(int h, int w){
    height = h;
    width = w;
    }
};

а так нет???

class area_cl{
public:
    int height;
    int width;
};

class cilinder: public area_cl{
public:cilinder(int h, int w): height(h), width(w){}
};

спасибо


Re: Конструктор. Ошибка C2614

От:

Юрий Жмеренецкий

ICQ 380412032
Дата:  28.09.09 09:21
Оценка:

Здравствуйте, zfima, Вы писали:

Z>почему так можно

[…]

Z>а так нет???


Z>

Z>class area_cl{
Z>public:
Z>    int height;
Z>    int width;
Z>};

Z>class cilinder: public area_cl{
Z>public:cilinder(int h, int w): height(h), width(w){}
Z>};
Z>

Вызов конструктора ‘cilinder’ должен привести к вызову конструктора area_cl, но запись ‘: height(h), width(w)’ никак не может быть таким вызовом (формально, в этом контексте не будут найдены имена height/width).

Вызывать конструктор базобого подобъекта нужно так:

class area_cl{
public:
    area_cl(int h, int w) : height(h), width(w){}
    int height;
    int width;
};

class cilinder: public area_cl{
    public:
        cilinder(int h, int w): area_cl(h, w){}
};


Re: Конструктор. Ошибка C2614

От:

Bell

Россия

 
Дата:  28.09.09 09:23
Оценка:

Здравствуйте, zfima, Вы писали:

Z>Здрасте.

Z>Коротко:
Z>почему так можно



Z>а так нет???

Тоже коротко: по определению.

12.6.2/2

Unless the meminitializer-id names a nonstatic data member of the constructor’s class or a direct or virtual base of that
class, the mem-initializer is ill-formed.

Любите книгу — источник знаний (с) М.Горький


Re[2]: Конструктор. Ошибка C2614

От:

zfima

 
Дата:  28.09.09 09:25
Оценка:

Здравствуйте, Юрий Жмеренецкий, Вы писали:

ЮЖ>Здравствуйте, zfima, Вы писали:


Z>>почему так можно


ЮЖ>[…]


Z>>а так нет???


Z>>

Z>>class area_cl{
Z>>public:
Z>>    int height;
Z>>    int width;
Z>>};

Z>>class cilinder: public area_cl{
Z>>public:cilinder(int h, int w): height(h), width(w){}
Z>>};
Z>>



ЮЖ>Вызов конструктора ‘cilinder’ должен привести к вызову конструктора area_cl, но запись ‘: height(h), width(w)’ никак не может быть таким вызовом (формально, в этом контексте не будут найдены имена height/width).


ЮЖ>Вызывать конструктор базобого подобъекта нужно так:

ЮЖ>

ЮЖ>class area_cl{
ЮЖ>public:
ЮЖ>    area_cl(int h, int w) : height(h), width(w){}
ЮЖ>    int height;
ЮЖ>    int width;
ЮЖ>};

ЮЖ>class cilinder: public area_cl{
ЮЖ>    public:
ЮЖ>        cilinder(int h, int w): area_cl(h, w){}
ЮЖ>};
ЮЖ>


Спасибо Юра!


Re[2]: Конструктор. Ошибка C2614

От:

Кодт

Россия

 
Дата:  28.09.09 10:27
Оценка:

Здравствуйте, Bell, Вы писали:

B>Тоже коротко: по определению.

Вообще-то, полезная фича была бы. При наследовании от POD-структур, например.

… << RSDN@Home 1.2.0 alpha 4 rev. 1237>>

http://files.rsdn.org/4783/catsmiley.gif Перекуём баги на фичи!


Re[3]: Конструктор. Ошибка C2614

От:

Erop

Россия

 
Дата:  29.09.09 17:08
Оценка:

Здравствуйте, Кодт, Вы писали:

К>Вообще-то, полезная фича была бы. При наследовании от POD-структур, например.

Чем при POD не устраивает потом присвоить?

Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно «ради красного словца». За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском


Re[4]: Конструктор. Ошибка C2614

От:

Кодт

Россия

 
Дата:  29.09.09 22:34
Оценка:

Здравствуйте, Erop, Вы писали:

E>Чем при POD не устраивает потом присвоить?

1) Пропадает видимость декларативности
Кстати, имеет ли право компилятор размещать статические константы типов с очевидными конструкторами в секции констант, как это он делает с агрегатной инициализацией? И если да — то насколько далеко заходит в очевидности?

struct A { int x,y; };
struct B { int x,y; B() : x(1), y(2) {} };
struct C { int x,y; C() { x=1; y=2; } };
struct D { int x,y; D() { x=0; y=2; ++x; } }; // наверно, уже не потянет

A const a = {1,2};
B const b;
C const c;
D const d;

2) Немного иной ход вычислений, из-за чего, скажем, не прокатит вот такое

struct A { ..... };
struct B
{
  B(A* neighbour) { ..... }
};
struct C : A, B
{
  C()
  : A(.....) // если у A есть содержательный конструктор, нам повезло
  , B((A*)this)
  {
    initialize_A(); // иначе B::B до этих данных не доберётся
  }
};

Мысленно подставь на место A(…..) инициализацию отдельных членов (которые нужны для B).
Но последнее, конечно, изврат.

http://files.rsdn.org/4783/catsmiley.gif Перекуём баги на фичи!

Подождите ...

Wait...

  • Переместить
  • Удалить
  • Выделить ветку

Пока на собственное сообщение не было ответов, его можно удалить.

У меня есть базовый класс «A», который имеет подкласс «B», который имеет подкласс «C», который имеет подкласс «D».

Я хочу, чтобы D вызывал «конструктор»,

D(int x,int y):A(x,y){};

но я получаю сообщение об ошибке: ошибка C2614: ‘D’: незаконная инициализация члена: ‘A’ не является базой или членом.

D может вызвать любой из конструкторов C, но это не то, что я хочу. Любая помощь будет оценена по достоинству.

    msm.ru

    Нравится ресурс?

    Помоги проекту!

    >
    косяк с шаблонным классом
    , template, наследование, инициализация в конструкторе

    • Подписаться на тему
    • Сообщить другу
    • Скачать/распечатать тему



    Сообщ.
    #1

    ,
    05.04.07, 11:48

      Senior Member

      ****

      Рейтинг (т): 41

      кратко обозвать проблему не сумел. как получится…

      ExpandedWrap disabled

        class Tag

        {

        public:

            Tag( void );  //определён в сырце

            Tag( const char *name, const char *lB, const char *rB, int opt );  //этот тоже есть в сырце

            virtual ~Tag( void );  //аналогично

            virtual inline bool IsOpening();  //вертает false

        protected:

            char *tagName;

            int options;

            char *leftBracket;

            char *rightBracket;

        };

        ……

        template <class Base>

        class Opening : public Base

        {

        public:

            Opening( ); // пустой. ниже в этом же хидере

            virtual ~Opening( void );

            virtual int SetClosing( Closing <Base> *cl );

            virtual inline bool IsOpening();  // вернёт true

        private:

            Closing <Base> *closing;

        };

        ……

        template <class Base>

        class HTML : public Base

        {

        public:

            HTML(void);

            virtual ~HTML(void);

        };

        template <class Base>

        HTML<Base>::HTML(void)

        {

        }

        template <class Base>

        HTML<Base>::~HTML(void)

        {

        }

        ……..

        class HTMLOpenTag : public HTML < Opening < Tag > >

        {

        public:

            HTMLOpenTag( const char *name, const char *lB, const char *rB, int opt );

            virtual ~HTMLOpenTag(void);

        };

      теперь пытаюсь в HTMLOpenTag поюзать конструктор Tag, тот, что параметры принимает:

      ExpandedWrap disabled

        HTMLOpenTag::HTMLOpenTag( const char *name, const char *lB, const char *rB, int opt )

            :   Tag( name, lB, rB, opt )

        {

            ;

        }

      ругается:
      error C2614: ‘HTMLOpenTag’ : illegal member initialization: ‘Tag’ is not a base or member

      если писать Tag::Tag(arguments), тоже ничего получается:
      error C2039: ‘__ctor’ : is not a member of ‘Tag’

      HTML<Opening<Tag > >::Opening<Tag>::Tag::Tag() — то же, что и в первом случае. ругается и на мембера, что он де не мембер вовсе…

      откуда руки растут, я знаю. вопрос — как исправить ситуёвину?

      забыл:
      VS 2003

      Сообщение отредактировано: ss — 05.04.07, 11:50


      Sazabis



      Сообщ.
      #2

      ,
      05.04.07, 12:28

        Цитата ss @ 05.04.07, 11:48

        error C2614: ‘HTMLOpenTag’ : illegal member initialization: ‘Tag’ is not a base or member

        Правильно, у тебя базовый Opening < Tag >, вот его и надо вызывать. А уже из него Tag


        ss



        Сообщ.
        #3

        ,
        05.04.07, 12:36

          Senior Member

          ****

          Рейтинг (т): 41

          а Tag значит уже не базовый?..
          Opening — это что-то абстрактное открывающее. неважно что — тэги, окна, двери… а я буду в нём создавать конструкторы, которые параметрами берёт чёрт-те-что? ему ни имя (name тэга), ни что бы то ни было не нужно для создания экземпляра. на то он и шаблон у меня, чтоб только о себе заботиться. так что мне надо с самого низа иерархии вызывать именно самый верхний конструктор, минуя все промежуточные уровни.

          вобщем, не подходит.


          trainer



          Сообщ.
          #4

          ,
          05.04.07, 12:37

            Цитата ss @ 05.04.07, 11:48

            если писать Tag::Tag(arguments), тоже ничего получается

            Это просто неправильно. По стандарту у конструкторов нет имен и их нельзя вызывать прямо(только косвенно через создание объекта), то, что MSVC это пропускает — это отклонение от стандарта.

            В списке инициализации можно указывать только прямых предков.


            ss



            Сообщ.
            #5

            ,
            05.04.07, 12:49

              Senior Member

              ****

              Рейтинг (т): 41

              значит кроме как через явное задание значений полям класса в самом «нижнем» в иерархии конструкторе никак больше не сделать? код дублировать, значица, придётся?.. :(


              ss



              Сообщ.
              #6

              ,
              06.04.07, 05:16

                Senior Member

                ****

                Рейтинг (т): 41

                нашёл решение.
                наследование должно быть виртуальным. тогда можно вызывать конструктор Tag( arguments ) напрямую.
                есть возражения?

                0 пользователей читают эту тему (0 гостей и 0 скрытых пользователей)

                0 пользователей:

                • Предыдущая тема
                • C/C++: Общие вопросы
                • Следующая тема

                Рейтинг@Mail.ru

                [ Script execution time: 0,0295 ]   [ 16 queries used ]   [ Generated: 5.06.23, 23:59 GMT ]  

                Я получаю следующую ошибку в C ++:

                ошибка C2614: ‘ChildClass’: инициализация недопустимого члена: ‘var1’ не является базовым или членом

                Class Base 
                {
                    protected:
                    int var1;
                public:
                    Base()
                    {
                        var1=0;
                    }
                }
                
                
                class Child : public Base
                {
                    int chld;
                    public: 
                    Child() : var1(0)
                    {
                        chld=1;
                    }
                }
                

                Я чувствую, что то, что я сделал, соответствует протоколу OO. Здесь var1 — член данных базового класса с защищенным в качестве спецификатора доступа. Таким образом, это может быть унаследовано, и оно станет частным в дочернем элементе.

                Не понимаю, почему я получаю сообщение об ошибке?

                2 ответа

                Лучший ответ

                Это не работает по той причине, которую сообщает вам сообщение об ошибке: вы можете использовать списки инициализаторов только с прямыми членами или базовыми классами.

                В вашем случае вам даже не нужно инициализировать var1, поскольку Base::Base() будет вызываться конструктором Child, который установит для var1 значение 0.

                Если вам нужно другое значение, вам придется перегрузить конструктор Base и вызвать его явно:

                class Base 
                {
                protected:
                     int var1;
                public:
                     Base() : var1(0)
                     {
                     }
                     Base(int x) : var1(x)
                     {
                     }
                };
                
                class Child:public Base
                {
                    int chld;
                public: 
                    Child(): Base(42) , chld(1)
                    {
                    }
                };
                


                25

                Luchian Grigore
                13 Апр 2012 в 13:34

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

                Class Base 
                {
                  protected:
                     int var1;
                     Base( int var ) : var1(var)
                     {}
                  public:
                     Base()
                     {
                        var1=0;
                     }
                };
                
                class Child:public Base
                {
                      int chld;
                   public: 
                      Child():Base(0)
                      {
                         chld=1;
                      }
                };
                


                6

                sharptooth
                13 Апр 2012 в 13:34

                Понравилась статья? Поделить с друзьями:
              • Ошибка компилятора c2572
              • Ошибка компиляции для платы ai thinker esp32 cam
              • Ошибка компиляции встроенного языка
              • Ошибка компиляции видеофильма диск заполнен
              • Ошибка компиляции видеофильма premiere pro неизвестная ошибка