3

When I compile code that includes the following header file I get an error message that says:

Graph.h:22: error: ISO C++ forbids in-class initialization of non-const 
static member `maxNumberOfNeighbors'

How can I declare and initialize a static member that is not const?

This is the .h file

#ifndef GRAPH_H
#define GRAPH_H

typedef char ElementType;
class Graph {
public:
    class Node {
    public:
        static int maxNumberOfNeighbors = 4;;
        int numberOfNeighbors;
        Node * neighbors;
        ElementType data;
        Node();
        Node(ElementType data);
        void addNeighbor(Node node);
    };

typedef Node* NodePtr;

Graph();
void addNode(Node node);
NodePtr getNeighbors(Node node);
bool hasCycle(Node parent);
private:
    NodePtr nodes;
    static int maxNumberOfNodes;
    int numberOfNodes;
};

#endif /* GRAPH_H */
StoryTeller - Unslander Monica
  • 165,132
  • 21
  • 377
  • 458
yara raffoul
  • 93
  • 1
  • 11
  • 2
    With c++17 you can define a static member inline, in the class body: `static inline int maxNumberOfNeighbors = 4;` Otherwise, you must first declare it in the class body, then define it outside. – Oliv May 13 '19 at 08:03
  • The "classic" way to handle `static` member variables, is to only *declare* them inside the class, then do the *definition* and (possible) initialization outside (in a single source file). – Some programmer dude May 13 '19 at 08:03

3 Answers3

6

The simplest course of action is to follow the advice of the error message. If it complains about the non-const static, make it const.

static int const maxNumberOfNeighbors = 4;

Especially considering it should be a constant anyway, going by its name. You aren't going to change the maximum, are you!?

Otherwise, if you intend to mutate it, only initialize and define it outside the class definition.

// At namespace scope, in one file
int Graph::Node::maxNumberOfNeighbors = 4;
StoryTeller - Unslander Monica
  • 165,132
  • 21
  • 377
  • 458
  • I do not want to to be const, because neighbors reference points to an array, in the constructor in the .cpp file. I do not want it to be const in case the array got filled so that I can move the contents to a bigger array and assign give the array back the pointer neighbors – yara raffoul May 13 '19 at 15:35
4

One can definitely have class static members which are not CV-qualified (non const and not volatile). It is just that one should not initialize them (give them value) when one declare them inside the class, based on current ISO C++ regulations. In Comparison, it is OK to do so for non static data members(regardless of CV-qualification) Since C++11.

Because static data members do not belong to any object, with the right access they can be assigned (and if they are not constant, they can be manipulated) outside of the class(keeping in mind the right scope operator). Also regardless of public/private declaration and CV-qualification, static data members can be initialized outside their class.

So one way for initializing static data members, is to do so in the same block-scope/namespace where their classes(outer class in case of sub-classes) are situated, but not inside any class scope.

For example:

class Graph {
public:
    class Node {
    public:
        static int maxNumberOfNeighbors;
       .
       .
       .
    };
.
.
.
};

int Graph::Node::maxNumberOfNeighbors = 4;
//also int Graph::Node::maxNumberOfNeighbors(4);


Good luck!

AKL
  • 1,367
  • 7
  • 20
-2
class Node {
public:
    static const int maxNumberOfNeighbors = 4;
};
robthebloke
  • 9,331
  • 9
  • 12