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
9,45411 gold badges49 silver badges67 bronze badges
asked Apr 13, 2012 at 9:31
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 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
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
-
Proposed as answer by
-
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
-
Proposed as answer by
Конструктор. Ошибка 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>>
Перекуём баги на фичи!
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).
Но последнее, конечно, изврат.
Перекуём баги на фичи!
- Переместить
- Удалить
- Выделить ветку
Пока на собственное сообщение не было ответов, его можно удалить.
У меня есть базовый класс «A», который имеет подкласс «B», который имеет подкласс «C», который имеет подкласс «D».
Я хочу, чтобы D вызывал «конструктор»,
D(int x,int y):A(x,y){};
но я получаю сообщение об ошибке: ошибка C2614: ‘D’: незаконная инициализация члена: ‘A’ не является базой или членом.
D может вызвать любой из конструкторов C, но это не то, что я хочу. Любая помощь будет оценена по достоинству.
|
|
|
косяк с шаблонным классом
, template, наследование, инициализация в конструкторе
- Подписаться на тему
- Сообщить другу
- Скачать/распечатать тему
|
|
Senior Member Рейтинг (т): 41 |
кратко обозвать проблему не сумел. как получится…
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, тот, что параметры принимает:
HTMLOpenTag::HTMLOpenTag( const char *name, const char *lB, const char *rB, int opt ) : Tag( name, lB, rB, opt ) { ; } ругается: если писать Tag::Tag(arguments), тоже ничего получается: HTML<Opening<Tag > >::Opening<Tag>::Tag::Tag() — то же, что и в первом случае. ругается и на мембера, что он де не мембер вовсе… откуда руки растут, я знаю. вопрос — как исправить ситуёвину? забыл: Сообщение отредактировано: ss — 05.04.07, 11:50 |
Sazabis |
|
Цитата ss @ 05.04.07, 11:48 error C2614: ‘HTMLOpenTag’ : illegal member initialization: ‘Tag’ is not a base or member Правильно, у тебя базовый Opening < Tag >, вот его и надо вызывать. А уже из него Tag |
ss |
|
Senior Member Рейтинг (т): 41 |
а Tag значит уже не базовый?.. вобщем, не подходит. |
trainer |
|
Цитата ss @ 05.04.07, 11:48 если писать Tag::Tag(arguments), тоже ничего получается Это просто неправильно. По стандарту у конструкторов нет имен и их нельзя вызывать прямо(только косвенно через создание объекта), то, что MSVC это пропускает — это отклонение от стандарта. В списке инициализации можно указывать только прямых предков. |
ss |
|
Senior Member Рейтинг (т): 41 |
значит кроме как через явное задание значений полям класса в самом «нижнем» в иерархии конструкторе никак больше не сделать? код дублировать, значица, придётся?.. |
ss |
|
Senior Member Рейтинг (т): 41 |
нашёл решение. |
0 пользователей читают эту тему (0 гостей и 0 скрытых пользователей)
0 пользователей:
- Предыдущая тема
- C/C++: Общие вопросы
- Следующая тема
[ 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