what's wrong with declaration of array in class

Discussion in 'C++' started by thomas, May 13, 2009.

  1. thomas

    thomas Guest

    Hi,
    -------------code----------
    #include<iostream>
    using namespace std;

    class maze{
    public:
    int dir[4][2] = {{1, 0}, {-1, 0}, {0, 1}, {0, -1}};
    void print(){
    cout<<"hello"<<endl;
    }
    };

    int main(){
    maze ins;
    ins.print();
    }
    ------------code-----------------

    The code cannot compile because of the declaration of the array "dir".
    But I don't get it? why is that?
     
    thomas, May 13, 2009
    #1
    1. Advertising

  2. * thomas:
    > Hi,
    > -------------code----------
    > #include<iostream>
    > using namespace std;
    >
    > class maze{
    > public:
    > int dir[4][2] = {{1, 0}, {-1, 0}, {0, 1}, {0, -1}};
    > void print(){
    > cout<<"hello"<<endl;
    > }
    > };
    >
    > int main(){
    > maze ins;
    > ins.print();
    > }
    > ------------code-----------------
    >
    > The code cannot compile because of the declaration of the array "dir".
    > But I don't get it? why is that?


    AFAIK there's no good reason, except historical accident, why the language is
    that way.

    In C++98 the only data members you can initialize directly in the declaration
    are static const of integral or enumeration type (I'm using that standard's
    terminology here -- as far as I'm concerned an enum is very integral!).

    That means that in C++98 you have the same problem almost no matter the type, e.g.

    class Amazing
    {
    double x = 5; // Nah!
    };

    One way out is to use a constructor initializer list, like

    class InstanceData
    {
    private:
    double x;
    public:
    InstanceData(): x( 5 ) {}
    };

    If, however, the data is constant and the same for all instances, as it seems
    your 'dir' array will be, then you can declare it static const,

    class ClassData
    {
    private:
    static double const x;
    public:
    // Whatever
    };

    double const ClassData::x = 5;

    where the last line, the value definition, needs to be in exactly one
    compilation unit and exactly once, i.e., don't put it in a header file.

    The corresponding for your maze:

    class Maze
    {
    private:
    static int const dir[4][2];
    public:
    // Whatever.
    };

    int const Maze::dir[4][2] =
    {{1, 0}, {-1, 0}, {0, 1}, {0, -1}};

    However, I suggest defining a class Point to handle those (x,y) values, instead
    of doing indexing or whatever -- it will save much work. :)


    Cheers & hth.,

    - Alf

    --
    Due to hosting requirements I need visits to <url: http://alfps.izfree.com/>.
    No ads, and there is some C++ stuff! :) Just going there is good. Linking
    to it is even better! Thanks in advance!
     
    Alf P. Steinbach, May 13, 2009
    #2
    1. Advertising

  3. thomas

    thomas Guest

    On May 13, 11:25 am, "Alf P. Steinbach" <> wrote:
    >
    > AFAIK there's no good reason, except historical accident, why the language is
    > that way.
    >
    > In C++98 the only data members you can initialize directly in the declaration
    > are static const of integral or enumeration type (I'm using that standard's
    > terminology here  --  as far as I'm concerned an enum is very integral!).
    >

    Oh, I see. In my opinion, maybe the designer think that only data
    stored globally (like static) can be initialized in a class. Local
    data should be initialized in a ctor. But I don't understand why he
    would take only static const integeral type specially. It just makes
    more confusions.

    > That means that in C++98 you have the same problem almost no matter the type, e.g.
    >
    >    class Amazing
    >    {
    >        double x = 5;   // Nah!
    >    };
    >
    > One way out is to use a constructor initializer list, like
    >
    >    class InstanceData
    >    {
    >    private:
    >        double x;
    >    public:
    >        InstanceData(): x( 5 ) {}
    >    };
    >
    > If, however, the data is constant and the same for all instances, as it seems
    > your 'dir' array will be, then you can declare it static const,
    >
    >    class ClassData
    >    {
    >    private:
    >        static double const x;
    >    public:
    >        // Whatever
    >    };
    >
    >    double const ClassData::x = 5;
    >
    > where the last line, the value definition, needs to be in exactly one
    > compilation unit and exactly once, i.e., don't put it in a header file.
    >

    Yes. But I don't want to declare a variable and bother going somewhere
    else to do initialization.
    > The corresponding for your maze:
    >
    >    class Maze
    >    {
    >    private:
    >        static int const dir[4][2];
    >    public:
    >        // Whatever.
    >    };
    >
    >    int const Maze::dir[4][2] =
    >        {{1, 0}, {-1, 0}, {0, 1}, {0, -1}};
    >
    > However, I suggest defining a class Point to handle those (x,y) values, instead
    > of doing indexing or whatever  --  it will save much work. :)
    >

    What I need is an const array of int. By const, I really mean that
    they will not be changed. And I expect they won't be used otherwhere.
    That's why I want them to be in the class scope. But the C++ standard
    makes it rather messy.
    > Cheers & hth.,
    >
    > - Alf
    >
    > --
    > Due to hosting requirements I need visits to <url:http://alfps.izfree.com/>.
    > No ads, and there is some C++ stuff! :) Just going there is good. Linking
    > to it is even better! Thanks in advance!- Hide quoted text -
    >
    > - Show quoted text -
     
    thomas, May 13, 2009
    #3
  4. thomas

    Neelesh Guest

    On May 13, 8:49 am, thomas <> wrote:
    > On May 13, 11:25 am, "Alf P. Steinbach" <> wrote:
    >
    > > AFAIK there's no good reason, except historical accident, why the language is
    > > that way.

    >
    > > In C++98 the only data members you can initialize directly in the declaration
    > > are static const of integral or enumeration type (I'm using that standard's
    > > terminology here  --  as far as I'm concerned an enum is very integral!).

    >
    > Oh, I see. In my opinion, maybe the designer think that only data
    > stored globally (like static) can be initialized in a class. Local
    > data should be initialized in a ctor. But I don't understand why he
    > would take only static const integeral type specially. It just makes
    > more confusions.
    >
    >
    >
    >
    >
    > > That means that in C++98 you have the same problem almost no matter the type, e.g.

    >
    > >    class Amazing
    > >    {
    > >        double x = 5;   // Nah!
    > >    };

    >
    > > One way out is to use a constructor initializer list, like

    >
    > >    class InstanceData
    > >    {
    > >    private:
    > >        double x;
    > >    public:
    > >        InstanceData(): x( 5 ) {}
    > >    };

    >
    > > If, however, the data is constant and the same for all instances, as it seems
    > > your 'dir' array will be, then you can declare it static const,

    >
    > >    class ClassData
    > >    {
    > >    private:
    > >        static double const x;
    > >    public:
    > >        // Whatever
    > >    };

    >
    > >    double const ClassData::x = 5;

    >
    > > where the last line, the value definition, needs to be in exactly one
    > > compilation unit and exactly once, i.e., don't put it in a header file.

    >
    > Yes. But I don't want to declare a variable and bother going somewhere
    > else to do initialization.
    >
    > > The corresponding for your maze:

    >
    > >    class Maze
    > >    {
    > >    private:
    > >        static int const dir[4][2];
    > >    public:
    > >        // Whatever.
    > >    };

    >
    > >    int const Maze::dir[4][2] =
    > >        {{1, 0}, {-1, 0}, {0, 1}, {0, -1}};

    >
    > > However, I suggest defining a class Point to handle those (x,y) values, instead
    > > of doing indexing or whatever  --  it will save much work. :)

    >
    > What I need is an const array of int.


    What you _really_ need is an "array of const int". an array is always
    "const", you can never make an array variable hold another array.


    >By const, I really mean that
    > they will not be changed. And I expect they won't be used otherwhere.
    > That's why I want them to be in the class scope.


    Giving a definition for a static member variable outside the class
    doesn't change its scope.
     
    Neelesh, May 13, 2009
    #4
  5. thomas

    thomas Guest


    > What you _really_ need is an "array of const int". an array is always
    > "const", you can never make an array variable hold another array.
    >

    Yeah. Good correction.
    > >By const, I really mean that
    > > they will not be changed. And I expect they won't be used otherwhere.
    > > That's why I want them to be in the class scope.

    >
    > Giving a definition for a static member variable outside the class
    > doesn't change its scope.- Hide quoted text -
    >

    Yes. But I have to take care of the member initialization outside the
    class. I just feel I am fitting my feet to another one's shoes. It's
    painful especially when there's no good reason.
     
    thomas, May 13, 2009
    #5
  6. * thomas:
    >> What you _really_ need is an "array of const int". an array is always
    >> "const", you can never make an array variable hold another array.
    >>

    > Yeah. Good correction.
    >>> By const, I really mean that
    >>> they will not be changed. And I expect they won't be used otherwhere.
    >>> That's why I want them to be in the class scope.

    >> Giving a definition for a static member variable outside the class
    >> doesn't change its scope.- Hide quoted text -
    >>

    > Yes. But I have to take care of the member initialization outside the
    > class. I just feel I am fitting my feet to another one's shoes. It's
    > painful especially when there's no good reason.


    It's just textual placement.

    It doesn't affect the scoping.

    There are some workarounds though, like ...

    class Maze
    {
    private:
    static int dir( int which, int xy )
    {
    static int const dirData[4][2] =
    {{1, 0}, {-1, 0}, {0, 1}, {0, -1}};
    return dirData[which][xy];
    }
    public:
    // Whatever
    };

    .... which allows you to have it all in a header file, if that's what you want.


    Cheers & hth.,

    - Alf

    --
    Due to hosting requirements I need visits to <url: http://alfps.izfree.com/>.
    No ads, and there is some C++ stuff! :) Just going there is good. Linking
    to it is even better! Thanks in advance!
     
    Alf P. Steinbach, May 13, 2009
    #6
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Noah
    Replies:
    5
    Views:
    986
  2. Alex Vinokur
    Replies:
    4
    Views:
    626
    Jonathan Turkanis
    Apr 5, 2004
  3. Ovidesvideo
    Replies:
    4
    Views:
    550
    Andrey Tarasevich
    Dec 10, 2004
  4. kelvSYC
    Replies:
    6
    Views:
    7,365
    Richard Herring
    May 17, 2005
  5. Replies:
    4
    Views:
    1,132
    Richard Tobin
    Dec 12, 2006
Loading...

Share This Page