Ошибка invalid use of non static data member

class Stack
{               
private:

    int tos;
    const int max = 10;    
    int a[max];
public:

    void push(int adddata);
    void pop();
    void printlist();
};

error: invalid use of non-static data member ‘max’

whats wrong in the code, and please help me with proper correction.
Thankyou

Jim Lewis's user avatar

Jim Lewis

43.4k7 gold badges81 silver badges96 bronze badges

asked Apr 19, 2015 at 18:32

user3584564's user avatar

It is mandatory that the array size be known during compile time for non-heap allocation (not using new to allocate memory).

If you are using C++11, constexpr is a good keyword to know, which is specifically designed for this purpose. [Edit: As pointed out by @bornfree in comments, it still needs to be static]

static constexpr int max = 10;

So, use static to make it a compile time constant as others have pointed out.

answered Apr 19, 2015 at 18:49

Titus's user avatar

TitusTitus

9078 silver badges18 bronze badges

2

As the error says, max is a non-static member of Stack; so you can only access it as part of a Stack object. You are trying to access it as if it were a static member, which exists independently of any objects.

Hence you need to make it static.

static const int max = 10;

If the initialization is in the header file then each file that includes the header file will have a definition of the static member. Thus during the link phase you will get linker errors as the code to initialize the variable will be defined in multiple source files.

answered Apr 19, 2015 at 18:43

Vinay Shukla's user avatar

Vinay ShuklaVinay Shukla

1,81813 silver badges41 bronze badges

As the compiler says make the data member static

static const int max = 10;    

answered Apr 19, 2015 at 18:35

Vlad from Moscow's user avatar

Vlad from MoscowVlad from Moscow

298k24 gold badges184 silver badges332 bronze badges

You need to make max a compile time constant:

static const int max = 10;

answered Apr 19, 2015 at 18:35

Johan Lundberg's user avatar

Johan LundbergJohan Lundberg

26.1k12 gold badges71 silver badges97 bronze badges

3

The Conceptual mistake that you are making is that you are trying to initialize values for the class in the class definition .This is the reason why constructors exist .Using a parametrized constructor set values of top of stack and its size.
When making the stack object pass the size of the stack to be created:

class Stack {               
private:
  int tos; 
  int a[max];

public:
  Stack(int s);
  void push(int adddata);
  void pop();
  void printlist();
};

Stack::Stack(int s) {
  tos=-1;
  max=s;
}

gudok's user avatar

gudok

4,0092 gold badges20 silver badges30 bronze badges

answered Feb 18, 2017 at 6:36

Anchellon's user avatar

class Stack
{               
private:

    int tos;
    const int max = 10;    
    int a[max];
public:

    void push(int adddata);
    void pop();
    void printlist();
};

error: invalid use of non-static data member ‘max’

whats wrong in the code, and please help me with proper correction.
Thankyou

Jim Lewis's user avatar

Jim Lewis

43.4k7 gold badges81 silver badges96 bronze badges

asked Apr 19, 2015 at 18:32

user3584564's user avatar

It is mandatory that the array size be known during compile time for non-heap allocation (not using new to allocate memory).

If you are using C++11, constexpr is a good keyword to know, which is specifically designed for this purpose. [Edit: As pointed out by @bornfree in comments, it still needs to be static]

static constexpr int max = 10;

So, use static to make it a compile time constant as others have pointed out.

answered Apr 19, 2015 at 18:49

Titus's user avatar

TitusTitus

9078 silver badges18 bronze badges

2

As the error says, max is a non-static member of Stack; so you can only access it as part of a Stack object. You are trying to access it as if it were a static member, which exists independently of any objects.

Hence you need to make it static.

static const int max = 10;

If the initialization is in the header file then each file that includes the header file will have a definition of the static member. Thus during the link phase you will get linker errors as the code to initialize the variable will be defined in multiple source files.

answered Apr 19, 2015 at 18:43

Vinay Shukla's user avatar

Vinay ShuklaVinay Shukla

1,81813 silver badges41 bronze badges

As the compiler says make the data member static

static const int max = 10;    

answered Apr 19, 2015 at 18:35

Vlad from Moscow's user avatar

Vlad from MoscowVlad from Moscow

298k24 gold badges184 silver badges332 bronze badges

You need to make max a compile time constant:

static const int max = 10;

answered Apr 19, 2015 at 18:35

Johan Lundberg's user avatar

Johan LundbergJohan Lundberg

26.1k12 gold badges71 silver badges97 bronze badges

3

The Conceptual mistake that you are making is that you are trying to initialize values for the class in the class definition .This is the reason why constructors exist .Using a parametrized constructor set values of top of stack and its size.
When making the stack object pass the size of the stack to be created:

class Stack {               
private:
  int tos; 
  int a[max];

public:
  Stack(int s);
  void push(int adddata);
  void pop();
  void printlist();
};

Stack::Stack(int s) {
  tos=-1;
  max=s;
}

gudok's user avatar

gudok

4,0092 gold badges20 silver badges30 bronze badges

answered Feb 18, 2017 at 6:36

Anchellon's user avatar

federovvania2

0 / 0 / 0

Регистрация: 17.10.2014

Сообщений: 14

1

17.10.2014, 17:27. Показов 2057. Ответов 15

Метки нет (Все метки)


Студворк — интернет-сервис помощи студентам

Добрый день.
Есть структура, понадобилось добавить в неё массив с дин. размером.

C#
1
2
3
4
5
6
struct MyStruct
{
    // ...
    uint16_t length;
    char data[length];
};

В итоге при компиляции получаю ошибку invalid use of non-static data member ‘MyStruct::length’

Как быть?



0



:)

Эксперт С++

4773 / 3267 / 497

Регистрация: 19.02.2013

Сообщений: 9,046

17.10.2014, 17:27

2

Цитата
Сообщение от federovvania2
Посмотреть сообщение

Как быть?

использовать std::vector<char> например.



0



federovvania2

0 / 0 / 0

Регистрация: 17.10.2014

Сообщений: 14

17.10.2014, 17:36

 [ТС]

3

Спасибо за ответ.

C++
1
2
uint16_t filesize;
std::vector<char> data(filesize);

error: ‘filesize’ is not a type

Что я не так делаю?

Попробовал вместо этих двух строк

C++
1
std::vector<char> data(uint16_t);

Также криво читает.

P.S. Может, здесь стоит уточнить, что я загружаю данные в структуру из файла.



0



Tulosba

:)

Эксперт С++

4773 / 3267 / 497

Регистрация: 19.02.2013

Сообщений: 9,046

17.10.2014, 17:43

4

Цитата
Сообщение от federovvania2
Посмотреть сообщение

Что я не так делаю?

Для этого нужно увидеть чуть больше, чем 2 строки кода. Если ты читаешь данные из файла и знаешь какого размера этот файл, то можно сразу зарезервировать нужное кол-во байт:

C++
1
2
uint16_t filesize = getFileSize(...);
std::vector<char> data(filesize);

после этого можно писать в ячейки от data[0] до data[filesize-1] включительно.



0



federovvania2

0 / 0 / 0

Регистрация: 17.10.2014

Сообщений: 14

17.10.2014, 17:50

 [ТС]

5

Проблема в том, что файл содержит массив MyStruct, и такой способ не подходит.

Я леплю объект

C++
1
MyStruct file[5];

И толкаю в него данные

C++
1
2
3
    ifstream in(filename,ios::binary|ios::in);
    in.read((char*)&file, sizeof file);
    in.close();

В итоге, если криво читается, то уже во втором элементе массива получается каша.



0



Форумчанин

Эксперт CЭксперт С++

8194 / 5044 / 1437

Регистрация: 29.11.2010

Сообщений: 13,453

17.10.2014, 17:52

6

А std::string нельзя?



0



0 / 0 / 0

Регистрация: 17.10.2014

Сообщений: 14

17.10.2014, 17:53

 [ТС]

7

Не понял, причем тут std::string, если я храню набор байт?
Если я про это не уточнил, извиняйте.



0



Форумчанин

Эксперт CЭксперт С++

8194 / 5044 / 1437

Регистрация: 29.11.2010

Сообщений: 13,453

17.10.2014, 17:55

8

Давайте всё условие задачи.



0



federovvania2

0 / 0 / 0

Регистрация: 17.10.2014

Сообщений: 14

17.10.2014, 18:01

 [ТС]

9

С радостью!

Есть файл со следующей структурой (синтаксис 010 editor)

Код

struct MyStruct {
    int num;
    uint size;
    char data[size];
} entries[5]

Необходимо корректно прочитать этот файл в массив.

Что я сделал
1. Затолкал саму структуру

C++
1
2
3
4
5
6
struct MyStruct
{
    int num;
    uint16_t length;
    char data[length];
};

«Десериализую» в массив

C++
1
2
3
4
5
6
    const char *filename = "TEST.DAT";
    Header header;
    MyStruct file[5];
    ifstream in(filename,ios::binary|ios::in);
    in.read((char*)&file, sizeof file);
    in.close();

При компиляции ошибка та самая, что в топике.



0



Tulosba

:)

Эксперт С++

4773 / 3267 / 497

Регистрация: 19.02.2013

Сообщений: 9,046

17.10.2014, 18:29

10

Размер структуры должен быть известен при компиляции. Так что поля типа

C++
1
char data[length];

где length не известна на момент компиляция не могут существовать.
Есть некоторый известный хак. Это сделать последнее поле структуры массивом неизвестного размера. Т.е. так:

C++
1
2
3
4
5
struct MyStruct
{
    uint16_t length;
    char data[];
};

И дальше уже можно будет приводить какую сырую память (выделенную в другом месте) к указателю на этот тип и более удобно работать с данными. Типа так:

C++
1
2
3
MyStruct* s = reinterpret_cast<MyStruct*>(d);
s->length; // используем длину
s->data[i]; // используем данные в диапазоне [0..length)



0



0 / 0 / 0

Регистрация: 17.10.2014

Сообщений: 14

17.10.2014, 18:40

 [ТС]

11

Не понял как здесь использовать последний код.
Да и если изменять размер data в структуре после заталкивания данных, оно же не даст эффекта.



0



Tulosba

:)

Эксперт С++

4773 / 3267 / 497

Регистрация: 19.02.2013

Сообщений: 9,046

17.10.2014, 18:57

12

Лучший ответ Сообщение было отмечено federovvania2 как решение

Решение

federovvania2, для начала надо всё-таки уяснить, что существование структуры вида:

C++
1
2
3
4
5
struct MyStruct {
    int num;
    uint size;
    char data[size];
}

невозможно в силу высказанных ранее причин (неизвестный размер поля).
Значит её нужно изменить. Как я уже предлагал, например на

C++
1
2
3
4
5
struct MyStruct {
    int num;
    int size;
    std::vector<char> data;
};

При чтении из файла делать следующее:
1. Прочитать «шапку», т.е. в данном случае
num и size:

C++
1
2
3
MyStruct s;
in.read( &s.num, sizeof(s.num) );
in.read( &s.size, sizeof(s.size) );

2. Зарезервировать память в векторе:

C++
1
s.data.resize(s.size);

3. Прочитать остальные данные:

C++
1
in.read( s.data.data(), s.size );

P.s. c приведениями типов в read(), я думаю, разберешься.



1



federovvania2

0 / 0 / 0

Регистрация: 17.10.2014

Сообщений: 14

17.10.2014, 21:33

 [ТС]

13

Не по теме:

Спасибо большое. Все работает как часы. :)

Добавлено через 2 часа 4 минуты
Камрады! Снова обращаюсь к вам.
Читаю я данные в бесконечном цикле пока !in.eof() т.е.

C++
1
2
3
4
5
6
7
while (!in.eof())
{
MyStruct file;
in.read((char*)&file.num, sizeof file.num);
// ...
collection.push_back(file);
}

Внезапно обнаружил, что последний элемент два раза пишется в коллекцию. С одной стороны понятно — поток кончается и объект уже не изменяется, но с другой… Почему поток не прерывается сразу как только поток попадает в состояние eof (или не попадает?).
Сейчас ситуация такая:
0B 00 00 00 0C 00 00 00

Программа толкает в массив:
11 (0B 00 00 00)
12 (0C 00 00 00)
12 (тут уже читать нечего из потока)

Я понимаю, если бы у меня оставался в конце байт непрочитанный, но чтение идет до упора.
Почему это происходит и как это побороть?



0



5230 / 3202 / 362

Регистрация: 12.12.2009

Сообщений: 8,112

Записей в блоге: 2

18.10.2014, 16:39

14

Цитата
Сообщение от Tulosba
Посмотреть сообщение

И дальше уже можно будет приводить какую сырую память (выделенную в другом месте) к указателю на этот тип и более удобно работать с данными. Типа так:

Что-то не понял — подразумевается, что первые 2 байта (sizeof(uint16_t)) содержат размер доступной памяти?



0



:)

Эксперт С++

4773 / 3267 / 497

Регистрация: 19.02.2013

Сообщений: 9,046

18.10.2014, 17:01

15

Kastaneda, именно так.



0



federovvania2

0 / 0 / 0

Регистрация: 17.10.2014

Сообщений: 14

18.10.2014, 19:22

 [ТС]

16

Я так понял, поток получает состояние EOF, когда происходит попытка чтения, а в потоке не осталось байт.
Решил проблему так:

C++
1
2
3
4
5
6
7
while(true)
MyStruct file;
in.read((char*)&file.num, sizeof file.num);
if (in.eof()) break;
// ...
collection.push_back(file);
}

Есть более нормальный способ решения?



0



To start with, I’m running windows 8 with Code::Blocks 12.11.

My main goal is to create a class named SCREEN with a member Array[][] and have this Array being modified and sending data to nested classes ‘Trim’ and ‘ScreenClass’.

To make my goal better understood, this could be achieved in another way: same class ‘SCREEN’ containing DIRECLTY all the functions contained in ‘Trim’ and ‘ScreenClass’, without these two classes ever being created.
BUT in those too classes, ‘Trim’ and ‘ScreenArray’, I will input MUCH code, MUCH functions and I don’t want them to be RAW in the ‘SCREEN’ class as finding each function then, would be a real trouble!! (I tried commenting like
//=========================================================
or 2 times the above, or even with asterisks (*) but when a lot of functions gather it’s getting baaaaad.)

To start visualizing it, I want something like this:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
class SCREEN
{
private:
    char Array[160][160];//[x],[y]
    int CurrentWidth;
    
    class ScreenClass
    {
    private:
        void Initialize()
        {
            Array[x][y]=' '; //This refers to SCREEN::Array
        }
    public:
        bool Set(int x,int y)
        {
            CurrentWidth=10; //This refers to SCREEN::CurrentWidth
            Array[x][y]=' '; //This refers to SCREEN::Array
        }
        char Get(int x,int y) 
        {
            return Array[x][y]; //This refers to SCREEN::Array
        }

        ScreenClass(){Initialize();}

    };
    ScreenClass ScreenArray;


    class TrimClass 
    {//... Like ScreenClass. If I complete correctly ScreenClass, I will complete correctly this too 
        
        void Clean()
        {
            Array[1][1]=' '; //This refers to SCREEN::Array
        }
    };
    TrimClass Trim;

    // --other Functions--


public:
    
    void Clean (char Background=' ')
    {
        ScreenArray.Set(x,y);
    }
    void CleanTrim (char Background=' ') //NOTE: Here after trim class
    {
        Trim.Clean(Background);
    }
    void CleanAll (char Background=' ')
    {
        CleanTrim(Background);
        Clean(Background);
    }

    
    // --other Functions--

    SCREEN()
    {
        
    }
};

Which is basiclly and my code….

I want to use it in the end like:

1
2
3
4
5
6
7
8
9
int main()
{
    SCREEN Screen;
    Screen.Clean();
    //or
    Screen.Trim.Clean();
}

So I don’t want to use any kind of static data..

I keep getting this error: invalid use of non-static data member ‘SCREEN::X’
where X is Array, CurrentWidth and other data of SCREEN.

I tried googling something like ‘nested classses error invalid use of non-static data member’ among other but wthout resault.

I know that in order to use anything from ScreenClass I have to create an Object of ScreenClass (which can obviousy be seen in my code xD), but what I also learned is that a class declared and defined within an enclosing class, is not a UNIQUE property of the enclosing-class…

Therefore Trim (of type TrimClass) and ScreenArray (of type ScreenClass) coud have been created and outside of SCREEN (altough their class was defined within SCREEN) and that is why they dont know which object of SCREEN they must use the data from.

Well I want EACH object of type ‘SCREEN’ to have it’s VERY OWN set of ‘Trim’ and ‘ScreenArray’ objects. To give an example:

1
2
3
4
class AClass
{
   int a;
}

In my exaple Each object of type AClass has it’s very OWN integer ‘a’, therefore a coding line of a=’something’, would never send an error implying that ‘a’ doesn’t know which object of AClass to edit ‘a’ from…. lol

Thanks in advance for any help :)

Extra info:

What I HAVE tried:

changing this

1
2
3
4
5
6
7
8
9
10
11
12
    class ScreenClass
    {
    private:
        void Initialize()
        {
            Array[x][y]=' '; //This refers to SCREEN::Array
        }
        //...
        ScreenClass(){Initialize();}

    };
    ScreenClass ScreenArray();

to this:

1
2
3
4
5
6
7
8
9
10
11
12
    class ScreenClass
    {
    private:
        void Initialize(SCREEN * const SCREENthis)
        {
            Array[x][y]=' '; //This refers to SCREEN::Array
        }
        //...
        ScreenClass(SCREEN * const SCREENthis){Initialize(SCREENthis);}

    };
    ScreenClass ScreenArray(this);

and all was fine…. except the last line ‘ScreenClass ScreenArray(this);’ where I got the error: expected identifier before ‘this’, and for the same line another error (or different aproach?): expected ‘,’ or ‘…’ before ‘this’

P.S.:
If that will help at all, my problem IN ABSTRACT is (in my point of view)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
class A
{
private/public/protected: (any of the three)
    //many data, from now on reffered to as A::Data.
private/public/protected:
    class B
    {
        void BFunction()
        {
            //Change A::data
        }
    }
    B b;
    
    void AFunction()
    {
        b.f();
    }
}

int main()
{
    A a;
    a.AFunction();

}

The member Trim of object Screen does not know that it is a member of that particular SCREEN object and therefore it does not know which Array to reference.

Each TrimClass object could have a pointer to its parent.

How? :D hahaha
I have no idea how to do this^^

Let’s say I add one «SCREEN* ScreenPtr» within ScreenClass….
Do I initiate it? Do I give it a value? Where? With what code?

And thanks for telling me that. I didn’t knew :)
Thanks a lot!

Last edited on

I didn’t see your addendum while posting. You were almost there.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
class A
{
  struct B
  {
    A * parent;

    B( A * p )
    : parent( p )
    {}

    void f()
    {
      cout << parent->data;
    }
  };

  int Data;
  B b;
    
public:
  A ()
  : Data( 42 ), b( this )
  {}

  void AFunction()
  {
    b.f();
  }
}

Last edited on

The Trim object is private, and therefore will not be able to be accessed from there(main).

Aceix.

Ok, REALY GOOD :D
but .. here are some questions: (xD)

In line 3: Why struct and not class?? O.o

In lines 7-8, 21-22: can I rewrite these this way-> «B(A*p) {parent = p;}», » A() {Data=42; b = this;}» ???? :D

It would help me A LOT (the way you wrote it gives me a headache to translate to something I understand :| .Nothing personal, Im talking about the so called «»Member initialization in constructors», if that is the correct name).

Another one. I have seen that before and I wοndered again about it,
in line 13: you reffer to «Data» while «Data» is FIRST time mentionedat line 17!! O.O
XD excuse my enthusiasm about this but I am new in programming and I don’t quite understand this, not yet :d

Thanks for the code! :D
I’ll go try it!

I’ll come back with the resaults :D

Again, thank you!

Line 3: unimportant. Use what you need.

The constructors. See member initializer list http://en.cppreference.com/w/cpp/language/initializer_list

Line 13. My mistake (twice). We can write the implementation later:

1
2
3
4
5
6
7
8
9
10
class A {
  class B {
    void f();
  };
  int Data;
};

void A::B::f() {
  cout << parent->Data;
}

HOOOOOOOOOOOOOOOOOLY SH…….!!!!!! (You know the rest of the word! :D :D :D :D :D :D :D I’m gonna throw a party!! :D :D :D :D :D :D WOOOOOHOOOOOOO!!!!

I run a test on a minimalistic version of the program and I get no errors! :D

It must have worked!! (though I’m quite tired to try on the real program, it’s 1:47 the late night right now here X| and I’m about to go to sleep)

I did ALL you said with an exception,
I didn’t use struct but i used class (as mentioned in my question before)
and one HUGE note. When Initializing A like this: A(){b=this} I get an error.
When I do it like you said: A():b(this) {} I don’t!! (*rubbing my eyes to see clearer).

I mean what the he*k!?!?!?! Isn’t it the same?
Just a different methode for initializing?? O.o
Any hint for what should I read to understand the difference?
I read this topic* about it and thought/understood that this: A(){b=this} and A():b(this){} would be the same. *Topic: http://www.cplusplus.com/doc/tutorial/classes/

And I don’t understand how the code in line 18 of your last code (as I see it 1:07 AM) works…. I mean it’s constructor needs 1 parameter. An A* .. how can I say «B b;» ?
I guess that A():b(this) {} is involved.. But how? O.O

Again REEEEEALLY THANK YOU! :D You’re the MAN! :)))))

@Aceix, thank you for your reply too :)
keskiverto was faster, problem solved! :D

Last edited on

I will see you tommorow. For today, have a good night (if it is night where you are right now) or a good day :)

…zZzZzZzZzZzZzZ (Necro is Fast asleep xD)

Hey, really sorry for not replying this long. I run into some troubles and I couldn’t continue with the program.
Right now I just got curious if I shall change the way my program is structured.. xD

I mean, if I go the way I am already up to, I have this

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
class SCREEN
{
        class ScreenClass
        {
                //...blah-blah...
                //....some more...

                ScreenClass(SCREEN* const ParentSCREEN)
        }
        ScreenClass ScreenArray;

        class TrimClass
        {
                class UpperTrim()
                {
                        //...blah-blah....
                        //this "blah-blah" above though requires a SCREEN and a ScreenClass....
                   Upper(SCREEN* const ParentSCREEN, ScreenClass* const ParentScreenClass)
                }
                UpperTrim Upper();
                class LowerTrim() //Almost same code with UpperTrim
                {} LowerTrim Lower;
                //.. Left, right and Corners classes as well.

                //And corners class is like THAT
                class CornersTrim
                {
                        class UpperRightCorner
                        {


                                UpperRight(ScREEN* const ParentSCREEN)
                        }
                        UpperRightCorner UpperRight;
                        //Same for Lower Right, UperLeft, LowerLeft ....                


                        CornersTrim(SREEN* const ParentSCREEN):UpperRight(ParentSCREEN),UpperLeft(...)//LowerRight and lowerleft
                        {}
                }
                CornersTrim Corners;


                TrimClass(SCREEN* const ParentSCREEN):Upper(ParentSCREEN,this), Lower(ParentSCREEN,this), Left(....), Right(....), Corenrs(....)
                {}
        }

        TrimClass Trim


        SCREEN():ScreenArray(this), Trim(this)
}

And I already guess that this option is not VIABLE! xD
I find this TOOOO much for something that simple.

Should I just imput classes like Trim and ScreenClass in Header files on top of the class SCREEN and use the same methode (all those pointers), or is there a better way?
example:

1
2
3
4
5
6
7
8
#include "Trim.h"
#include "ScreenClass.h"

SCREEN
{
    TrimClass Trim
    //etc
}

The above would put less «strein», and would require less effort to read for the SCREEN class. ( I think..)

I thought of doing this: Instead of creating classes for manipulating the Trim and the Array in my SCREEN class, to just make simple fuctions, and to deal with the large amount of code in a single class, to include in headers the functions of my SCREEN class categorized.

In example:

1
2
3
4
5
6
SCREEN
{
    #include "TrimFunctions.h"
    #include "ArrayFunctions.h"

}

But aren’t wesupposed to only include DECLARATION of CLASSES in headers? O.o

I’m pretty stuck.

Hmmm, another though:

Since my SCREEN is a suplementary class, and not to work on it’s own (well it can, but it is not intended. I want it for other programs) , should I create an easy to see and maintain interface of it at a header SCREEN.h and then just define the functions at a SCREEN.cpp?

Help? :D
Serioucly, any help apreciated!
I’m new at programming and I can’t say I found my way yet

Last edited on

Solution 1

In C++, unlike (say) Java, an instance of a nested class doesn’t intrinsically belong to any instance of the enclosing class. So bar::getA doesn’t have any specific instance of foo whose a it can be returning. I’m guessing that what you want is something like:

    class bar {
      private:
        foo * const owner;
      public:
        bar(foo & owner) : owner(&owner) { }
        int getA() {return owner->a;}
    };

But even for this you may have to make some changes, because in versions of C++ before C++11, unlike (again, say) Java, a nested class has no special access to its enclosing class, so it can’t see the protected member a. This will depend on your compiler version. (Hat-tip to Ken Wayne VanderLinde for pointing out that C++11 has changed this.)

Solution 2

In C++, nested classes are not connected to any instance of the outer class. If you want bar to access non-static members of foo, then bar needs to have access to an instance of foo. Maybe something like:

class bar {
  public:
    int getA(foo & f ) {return foo.a;}
};

Or maybe

class bar {
  private:
    foo & f;

  public:
    bar(foo & g)
    : f(g)
    {
    }

    int getA() { return f.a; }
};

In any case, you need to explicitly make sure you have access to an instance of foo.

Solution 3

The nested class doesn’t know about the outer class, and protected doesn’t help. You’ll have to pass some actual reference to objects of the nested class type. You could store a foo*, but perhaps a reference to the integer is enough:

class Outer
{
    int n;

public:
    class Inner
    {
        int & a;
    public:
        Inner(int & b) : a(b) { }
        int & get() { return a; }
    };

    // ...  for example:

    Inner inn;
    Outer() : inn(n) { }
};

Now you can instantiate inner classes like Inner i(n); and call i.get().

Related videos on Youtube

Static Data Members & Methods in C++ OOPS | C++ Tutorials for Beginners #24

17 : 48

Static Data Members & Methods in C++ OOPS | C++ Tutorials for Beginners #24

7.14 Why Non-Static variables does not work in Static method in Java?

04 : 53

7.14 Why Non-Static variables does not work in Static method in Java?

Error: "invalid use of non-static member function" while calling a function from my own...

02 : 46

Error: «invalid use of non-static member function» while calling a function from my own…

Static Data Members in C++ & Static Member Functions in C++|C++ programming tutorials for Beginners

11 : 15

Static Data Members in C++ & Static Member Functions in C++|C++ programming tutorials for Beginners

Arduino: error: invalid use of non-static member function attachInterrupt(0,count,RISING);

02 : 11

Arduino: error: invalid use of non-static member function attachInterrupt(0,count,RISING);

C++ Programming Tutorial 91 - Static Data Members

08 : 10

C++ Programming Tutorial 91 — Static Data Members

Comments

  • For a code like this:

    class foo {
      protected:
        int a;
      public:
        class bar {
          public:
            int getA() {return a;}   // ERROR
        };
        foo()
          : a (p->param)
    };
    

    I get this error:

     invalid use of non-static data member 'foo::a'
    

    currently the variable a is initialized in the constructor of foo.

    if I make it static, then it says:

     error: 'int foo::a' is a static data member; it can only be initialized at its definition
    

    However I want to pass a value to a in the constructor.
    What is the solution then?

    • why don’t you move getA() to foo?

    • The code in your question has several problems that make it unclear what you’re really trying to do. Please edit you question to indicate what your overall goal is.

  • there is no difference when I make a as public

  • @mahmood: b is the local argument of the constructor.

  • @mahmood within bar-class a doesn’t exist at all, it’s a part of foo-class. What are you trying to achieve?

  • p->param is something that read a value from somewhere else and pass it to a. For example, in a file, I wrote ‘2’. the code reads that and pass to a

  • @mahmood I asked because your code example isn’t full, so maybe that’s why what you want to do with your code isn’t clear

  • type of a is int. Why do you write foo *?

  • I’m aware that a is of type int. I’m not sure what part of my answer confused you in that respect. :-/

  • it says error: invalid conversion from 'foo*' to 'int' [-fpermissive]

  • You should probably note that access rights have changed in C++11. Now the standard reads: «A nested class is a member and as such has the same access rights as any other member».

  • foo * means «a pointer to an object of type foo«. I was assuming that you wanted each instance of bar to have an «owner» that’s an instance of foo; in which case, it needs to have a pointer to that owner. Did I assume wrongly?

  • @mahmood: That probably means that you wrote return owner; instead of return owner->a;.

  • @KenWayneVanderLinde: Good to know, thanks! I’ll update my answer.

Recents

Related

  • Ошибка invalid use of incomplete type class ui mainwindow
  • Ошибка invalid use of incomplete type class qdebug
  • Ошибка invalid stfs package horizon что делать
  • Ошибка invalid start mode archive offset что делать
  • Ошибка invalid signature detected check secure boot policy in setup как исправить