Thread: Can you initialize arrays in the class declaration

  1. #1
    Registered User
    Join Date
    Dec 2005
    Location
    german border
    Posts
    72

    Can you initialize arrays in the class declaration

    Hi,

    I am writing a simple chat program using Qt4. I decided to convert all text which is sent over the network into morse code as a side task to better understand string manipulation. I am having problems compiling now though. This is my first OO program and I decided to put the two arrays I use for conversion in the class header as private. I have other variables in the header file, but I had to make them const static to stop the compiler complaining. However the compiler still gives me errors with the arrays, they are below

    Code:
    In file included from kether.cpp:6:
    kether.h:40: error: a brace-enclosed initializer is not allowed here before ‘{’ token
    kether.h:66: error: invalid in-class initialization of static data member of non-integral type ‘const char [26][6]’
    kether.h:67: error: a brace-enclosed initializer is not allowed here before ‘{’ token
    kether.h:68: error: invalid in-class initialization of static data member of non-integral type ‘const char [26]
    Here is the relevant section from the header file

    Code:
    public slots:
            QString morseToText(QString morseCode);
            QString textToMorse(QString message);
            void on_ipConnect_clicked();
            void on_ipDisconnect_clicked();
            void on_ipAddress_textEdited();
            void on_sendMessage_clicked();
            void on_messageEntry_textEdited(QString message);
            void on_listen_clicked();
            void readData();
            void reportDisconnect();
            void connectedToHost();
            void handleNewConnection();
        private:
            Ui::kether ui;
    
            QTcpSocket *tcpSocket;
            QTcpServer *tcpServer;
    
            const static quint16 port = 9001;
            qint64 oneByte;
            char endOfCharacter;
            const static char morse[26][6] = {{'.','-','\0'}, //a
                                {'-','.','.','.','\0'}, //b
                                {'-','.','-','.','\0'}, //c
                                {'-','.','.','\0'}, //d
                                {'.','\0'}, //e
                                {'.','.','-','.','\0'}, //f
                                {'-','-','.','\0'}, //g
                                {'.','.','.','.','\0'}, //h
                                {'.','.','\0'}, //i
                                {'.','-','-','-','\0'}, //j
                                {'-','.','-','\0'}, //k
                                {'.','-','.','.','\0'}, //l
                                {'-','-','\0'}, //m
                                {'-','.','\0'}, //n
                                {'-','-','-','\0'}, //o
                                {'.','-','-','.','\0'}, //p
                                {'-','-','.','-','\0'}, //q
                                {'.','-','.','\0'}, //r
                                {'.','.','.','\0'}, //s
                                {'-','\0'}, //t
                                {'.','.','-','\0'}, //u
                                {'.','.','.','-','\0'}, //v
                                {'.','-','-','\0'}, //w
                                {'-','.','.','-','\0'}, //x
                                {'-','.','-','-','\0'}, //y
                                {'-','-','.','.','\0'} //z
            };
            const static char lookup[26] = {'a','b','c','d','e','f','g','h','i','j','k','l','m'
                              ,'n','o','p','q','r','s','t','u','v','w','x','y','z'};
    Additionally, the compiler claims none of the variables used in the two morseCode functions have been declared even though some of them are used elsewhere in the program without problems (Ui::kether ui). This is pretty confusing as the functions are members of the class as seen above. The errors and the functions are below

    Code:
    kether.cpp: In function ‘QString morseToText(QString)’:
    kether.cpp:147: error: ‘endOfCharacter’ was not declared in this scope
    kether.cpp:158: error: ‘ui’ was not declared in this scope
    kether.cpp:160: error: ‘morse’ was not declared in this scope
    kether.cpp:167: error: ‘lookup’ was not declared in this scope
    kether.cpp: In function ‘QString textToMorse(QString)’:
    kether.cpp:183: error: ‘lookup’ was not declared in this scope
    kether.cpp:186: error: ‘morse’ was not declared in this scope
    kether.cpp:191: error: ‘endOfCharacter’ was not declared in this scope
    Code:
    QString morseToText(QString morseCode)
    {
        QString message;
        int k,lastmarker,counter = 0;
        for(int j = 0;j < morseCode.size();j++)
        {
            while((k = morseCode.indexOf(endOfCharacter, k)) != -1)
            {
                QString character;
                for(int l = lastmarker;l < k; l++)
                {
                    character = morseCode[l];
                }
                for(int m = 0; m < character.size();m++)
                {
                    if(counter > 25)
                    {
                        ui.chatWindow->append("Decoding of message failed, this should never happen.");
                    }
                    else if(character[m] != morse[counter][m])
                    {
                        counter++;
                        m = 0;
                    }
                    else if(morse[counter][m] == NULL)
                    {
                        message.append(lookup[counter]);
                    }
    
                }
                k++;
            }
        }
    }
    
    QString textToMorse(QString message)
    {
        QString morseCode;
        for(int j = 0;j < message.size();j++)
        {
            for(int i = 0; i < 26; i++)
            {
                if(message[j] == lookup[i])
                {
                    int k = 0;
                    while(morse[i][k] != NULL)
                    {
                        morseCode.append(morse[i][k]);
                        k++;
                    }
                    morseCode.append(endOfCharacter);
                }
            }
        }
    }
    I'm sorry for the length of this post, I tried to cut out as much irrelevant code as possible. I figure this is probably a very simple problem, but after reading through some websites about OO I can't see anything obvious. Any ideas?

  2. #2
    C++ Witch laserlight's Avatar
    Join Date
    Oct 2003
    Location
    Singapore
    Posts
    28,413
    I believe the solution is:

    In the class definition, declare:
    Code:
    const char lookup[26];
    Then in the source file, implement:
    Code:
    const char Kether::lookup[26] = {'a','b','c','d','e','f','g','h','i','j','k','l','m'
                              ,'n','o','p','q','r','s','t','u','v','w','x','y','z'};
    The same goes for the other static const array.

    Additionally, the compiler claims none of the variables used in the two morseCode functions have been declared even though some of them are used elsewhere in the program without problems (Ui::kether ui). This is pretty confusing as the functions are members of the class as seen above. The errors and the functions are below
    It looks like you did not qualify the member functions with the class name when implementing them, e.g.,
    Code:
    QString Kether::textToMorse(QString message)
    {
    Last edited by laserlight; 02-23-2008 at 12:13 PM. Reason: Guessing the class is named Kether, not QString.
    Quote Originally Posted by Bjarne Stroustrup (2000-10-14)
    I get maybe two dozen requests for help with some sort of programming or design problem every day. Most have more sense than to send me hundreds of lines of code. If they do, I ask them to find the smallest example that exhibits the problem and send me that. Mostly, they then find the error themselves. "Finding the smallest program that demonstrates the error" is a powerful debugging tool.
    Look up a C++ Reference and learn How To Ask Questions The Smart Way

  3. #3
    Frequently Quite Prolix dwks's Avatar
    Join Date
    Apr 2005
    Location
    Canada
    Posts
    8,057
    Code:
                                {'.','\0'}, //e
                                {'.','.','-','.','\0'}, //f
                                {'-','-','.','\0'}, //g
    There's really a much easier way to do that . . . .
    Code:
                                ".", //e
                                "..-.", //f
                                "--.", //g
    It's exactly the same thing. String literals automatically add in a NULL terminator.
    dwk

    Seek and ye shall find. quaere et invenies.

    "Simplicity does not precede complexity, but follows it." -- Alan Perlis
    "Testing can only prove the presence of bugs, not their absence." -- Edsger Dijkstra
    "The only real mistake is the one from which we learn nothing." -- John Powell


    Other boards: DaniWeb, TPS
    Unofficial Wiki FAQ: cpwiki.sf.net

    My website: http://dwks.theprogrammingsite.com/
    Projects: codeform, xuni, atlantis, nort, etc.

  4. #4
    Registered User
    Join Date
    Dec 2005
    Location
    german border
    Posts
    72
    Thanks for the replies. I'm still getting errors compiling after making the changes however

    Code:
    kether.cpp: In constructor ‘Kether::Kether(QWidget*)’:
    kether.cpp:8: error: uninitialized member ‘Kether::morse’ with ‘const’ type ‘const char [26][6]’
    kether.cpp:8: error: uninitialized member ‘Kether::lookup’ with ‘const’ type ‘const char [26]’
    kether.cpp:14: error: invalid use of qualified-name ‘Kether::lookup’
    kether.cpp:16: error: invalid use of qualified-name ‘Kether::morse’
    I managed to get the 'uninitialized member' errors away by removing the const in the declarations in the header file, but even if I remove the ones in the source file as well the 'invalid' errors still persist. Thanks.

  5. #5
    Hurry Slowly vart's Avatar
    Join Date
    Oct 2006
    Location
    Rishon LeZion, Israel
    Posts
    6,788
    Maybe I do not undestand your problem. Here is what I did:

    test.h:
    Code:
    class test
    {
    	static const char arr[3][4] ;
    public:
    	test(void);
    public:
    	~test(void);
    };
    
    const char test::arr[3][4] = {"a", "bb", "ccc"};
    test.cpp:
    Code:
    #include "test.h"
    #include <iostream>
    
    int main()
    {
    	test t;
    }
    
    test::test(void)
    {
    	std::cout << this->arr[0][0];
    }
    
    test::~test(void)
    {
    }
    All problems in computer science can be solved by another level of indirection,
    except for the problem of too many layers of indirection.
    – David J. Wheeler

  6. #6
    Registered User
    Join Date
    Dec 2005
    Location
    german border
    Posts
    72
    Well, your test example above works fine for me. But when I declare the two arrays outside the class like yours I still get errors, and member functions apparently can't see them

    Code:
    In file included from kether.cpp:6:
    kether.h:43: error: ‘const char Kether::morse [26][6]’ is not a static member of ‘class Kether’
    kether.h:70: error: ‘const char Kether::lookup [26]’ is not a static member of ‘class Kether’
    kether.cpp: In member function ‘QString Kether::morseToText(QString)’:
    kether.cpp:202: error: ‘morse’ was not declared in this scope
    kether.cpp:209: error: ‘lookup’ was not declared in this scope
    kether.cpp: In member function ‘QString Kether::textToMorse(QString)’:
    kether.cpp:226: error: ‘lookup’ was not declared in this scope
    kether.cpp:229: error: ‘morse’ was not declared in this scope
    I am using a few other programs when compiling my chat program(moc etc..) whereas I just used g++ for your test example could this be the problem?

    Code:
    #ifndef KETHER_H
    #define KETHER_H
    #include <QTcpSocket>
    #include <QTcpServer>
    #include <QString>
    #include <QDate>
    
    #include "ui_kether.h"
    
    class QTcpSocket;
    class QTcpServer;
    
    class Kether : public QWidget
    {
        Q_OBJECT
    
        public:
            Kether(QWidget *parent = 0);
        public slots:
            QString morseToText(QString morseCode);
            QString textToMorse(QString message);
            void on_ipConnect_clicked();
            void on_ipDisconnect_clicked();
            void on_ipAddress_textEdited();
            void on_sendMessage_clicked();
            void on_messageEntry_textEdited(QString message);
            void on_listen_clicked();
            void readData();
            void reportDisconnect();
            void connectedToHost();
            void handleNewConnection();
        private:
            Ui::kether ui;
    
            QTcpSocket *tcpSocket;
            QTcpServer *tcpServer;
            QDate todaysDate;
            QString dateFormat, logFileName;
            const static quint16 port = 9001;
            qint64 oneByte;
            char endOfCharacter;
    };
        const char Kether::morse[26][6] = {{'.','-','\0'}, //a
                                {'-','.','.','.','\0'}, //b
                                {'-','.','-','.','\0'}, //c
                                {'-','.','.','\0'}, //d
                                {'.','\0'}, //e
                                {'.','.','-','.','\0'}, //f
                                {'-','-','.','\0'}, //g
                                {'.','.','.','.','\0'}, //h
                                {'.','.','\0'}, //i
                                {'.','-','-','-','\0'}, //j
                                {'-','.','-','\0'}, //k
                                {'.','-','.','.','\0'}, //l
                                {'-','-','\0'}, //m
                                {'-','.','\0'}, //n
                                {'-','-','-','\0'}, //o
                                {'.','-','-','.','\0'}, //p
                                {'-','-','.','-','\0'}, //q
                                {'.','-','.','\0'}, //r
                                {'.','.','.','\0'}, //s
                                {'-','\0'}, //t
                                {'.','.','-','\0'}, //u
                                {'.','.','.','-','\0'}, //v
                                {'.','-','-','\0'}, //w
                                {'-','.','.','-','\0'}, //x
                                {'-','.','-','-','\0'}, //y
                                {'-','-','.','.','\0'} //z
        };
        const char Kether::lookup[26] = {'a','b','c','d','e','f','g','h','i','j','k','l','m'
        ,'n','o','p','q','r','s','t','u','v','w','x','y','z'};
    #endif

  7. #7
    Hurry Slowly vart's Avatar
    Join Date
    Oct 2006
    Location
    Rishon LeZion, Israel
    Posts
    6,788
    AS error says - I do not see these two lines inside your class definition

    Code:
    static const char morse[26][6];
    static const char lookup[26];
    Do I miss them or you?
    All problems in computer science can be solved by another level of indirection,
    except for the problem of too many layers of indirection.
    – David J. Wheeler

  8. #8
    Registered User
    Join Date
    Dec 2005
    Location
    german border
    Posts
    72
    Yeah sorry forgot those lines. I added them but then I get errors during linking as far as I can tell.

    Code:
    main.o:(.rodata+0x0): multiple definition of `Kether::morse'
    kether.o:(.rodata+0x0): first defined here
    main.o:(.rodata+0x9c): multiple definition of `Kether::lookup'
    kether.o:(.rodata+0x9c): first defined here
    moc_kether.o:(.rodata+0x40): multiple definition of `Kether::morse'
    kether.o:(.rodata+0x0): first defined here
    moc_kether.o:(.rodata+0xdc): multiple definition of `Kether::lookup'
    kether.o:(.rodata+0x9c): first defined here
    Last edited by Calef13; 02-24-2008 at 01:19 PM.

  9. #9
    Hurry Slowly vart's Avatar
    Join Date
    Oct 2006
    Location
    Rishon LeZion, Israel
    Posts
    6,788
    you are missing /code in the closing tag

    try to move array initialization into one of cpp files
    All problems in computer science can be solved by another level of indirection,
    except for the problem of too many layers of indirection.
    – David J. Wheeler

  10. #10
    Registered User
    Join Date
    Dec 2005
    Location
    german border
    Posts
    72
    I moved it into the source file but then I get these errors

    Code:
    kether.cpp: In constructor ‘Kether::Kether(QWidget*)’:
    kether.cpp:14: error: invalid use of qualified-name ‘Kether::lookup’
    kether.cpp:16: error: invalid use of qualified-name ‘Kether::morse’
    If I remove the 'Kether::' part from the initialization in the source file I get errors about undefined references.

  11. #11
    Hurry Slowly vart's Avatar
    Join Date
    Oct 2006
    Location
    Rishon LeZion, Israel
    Posts
    6,788
    could you show the last code, because once again - just moving array initialization into cpp file - works fine for me
    All problems in computer science can be solved by another level of indirection,
    except for the problem of too many layers of indirection.
    – David J. Wheeler

  12. #12
    Registered User
    Join Date
    Dec 2005
    Location
    german border
    Posts
    72
    Here is the header file and some of the source file, if you want to see more code just ask.

    Code:
    #ifndef KETHER_H
    #define KETHER_H
    #include <QTcpSocket>
    #include <QTcpServer>
    #include <QString>
    #include <QDate>
    
    #include "ui_kether.h"
    
    class QTcpSocket;
    class QTcpServer;
    
    class Kether : public QWidget
    {
        Q_OBJECT
    
        public:
            Kether(QWidget *parent = 0);
        public slots:
            QString morseToText(QString morseCode);
            QString textToMorse(QString message);
            void on_ipConnect_clicked();
            void on_ipDisconnect_clicked();
            void on_ipAddress_textEdited();
            void on_sendMessage_clicked();
            void on_messageEntry_textEdited(QString message);
            void on_listen_clicked();
            void readData();
            void reportDisconnect();
            void connectedToHost();
            void handleNewConnection();
        private:
            Ui::kether ui;
    
            QTcpSocket *tcpSocket;
            QTcpServer *tcpServer;
            QDate todaysDate;
            QString dateFormat, logFileName;
            const static quint16 port = 9001;
            qint64 oneByte;
            char endOfCharacter;
            static const char morse[26][6];
            static const char lookup[26];
    };
     /*   const char Kether::morse[26][6] = {{'.','-','\0'}, //a
                                {'-','.','.','.','\0'}, //b
                                {'-','.','-','.','\0'}, //c
                                {'-','.','.','\0'}, //d
                                {'.','\0'}, //e
                                {'.','.','-','.','\0'}, //f
                                {'-','-','.','\0'}, //g
                                {'.','.','.','.','\0'}, //h
                                {'.','.','\0'}, //i
                                {'.','-','-','-','\0'}, //j
                                {'-','.','-','\0'}, //k
                                {'.','-','.','.','\0'}, //l
                                {'-','-','\0'}, //m
                                {'-','.','\0'}, //n
                                {'-','-','-','\0'}, //o
                                {'.','-','-','.','\0'}, //p
                                {'-','-','.','-','\0'}, //q
                                {'.','-','.','\0'}, //r
                                {'.','.','.','\0'}, //s
                                {'-','\0'}, //t
                                {'.','.','-','\0'}, //u
                                {'.','.','.','-','\0'}, //v
                                {'.','-','-','\0'}, //w
                                {'-','.','.','-','\0'}, //x
                                {'-','.','-','-','\0'}, //y
                                {'-','-','.','.','\0'} //z
        };
        const char Kether::lookup[26] = {'a','b','c','d','e','f','g','h','i','j','k','l','m'
        ,'n','o','p','q','r','s','t','u','v','w','x','y','z'};*/
    #endif
    Relevant part of the constructor:

    Code:
        const char Kether::lookup[26] = {'a','b','c','d','e','f','g','h','i','j','k','l','m'
        ,'n','o','p','q','r','s','t','u','v','w','x','y','z'};
        const char Kether::morse[26][6] = {{'.','-','\0'}, //a
                                {'-','.','.','.','\0'}, //b
                                {'-','.','-','.','\0'}, //c
                                {'-','.','.','\0'}, //d
                                {'.','\0'}, //e
                                {'.','.','-','.','\0'}, //f
                                {'-','-','.','\0'}, //g
                                {'.','.','.','.','\0'}, //h
                                {'.','.','\0'}, //i
                                {'.','-','-','-','\0'}, //j
                                {'-','.','-','\0'}, //k
                                {'.','-','.','.','\0'}, //l
                                {'-','-','\0'}, //m
                                {'-','.','\0'}, //n
                                {'-','-','-','\0'}, //o
                                {'.','-','-','.','\0'}, //p
                                {'-','-','.','-','\0'}, //q
                                {'.','-','.','\0'}, //r
                                {'.','.','.','\0'}, //s
                                {'-','\0'}, //t
                                {'.','.','-','\0'}, //u
                                {'.','.','.','-','\0'}, //v
                                {'.','-','-','\0'}, //w
                                {'-','.','.','-','\0'}, //x
                                {'-','.','-','-','\0'}, //y
                                {'-','-','.','.','\0'} //z
        };

  13. #13
    C++ Witch laserlight's Avatar
    Join Date
    Oct 2003
    Location
    Singapore
    Posts
    28,413
    Those are static const arrays. They are initialised outside of the constructor, in this case in the source file (without the static keyword). So it looks like you just need to take them out of the constructor.
    Quote Originally Posted by Bjarne Stroustrup (2000-10-14)
    I get maybe two dozen requests for help with some sort of programming or design problem every day. Most have more sense than to send me hundreds of lines of code. If they do, I ask them to find the smallest example that exhibits the problem and send me that. Mostly, they then find the error themselves. "Finding the smallest program that demonstrates the error" is a powerful debugging tool.
    Look up a C++ Reference and learn How To Ask Questions The Smart Way

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Problem with friend class declaration in a namespace
    By Angus in forum C++ Programming
    Replies: 2
    Last Post: 12-09-2008, 01:29 PM
  2. Forward Declaration of Class Members?
    By 691175002 in forum C++ Programming
    Replies: 3
    Last Post: 01-17-2008, 10:34 PM
  3. Screwy Linker Error - VC2005
    By Tonto in forum C++ Programming
    Replies: 5
    Last Post: 06-19-2007, 02:39 PM
  4. Replies: 4
    Last Post: 04-02-2004, 07:30 PM
  5. Warnings, warnings, warnings?
    By spentdome in forum C Programming
    Replies: 25
    Last Post: 05-27-2002, 06:49 PM