Thread: How to initialize a string array in a default class constructor?

  1. #1
    Registered User
    Join Date
    Mar 2005
    Posts
    37

    How to initialize a string array in a default class constructor?

    Pulling my hair out on this one, book doesn't show any examples and my GoogleFu is weak.

    Code:
    #ifndef ROMANNUMERALS_H_INCLUDED
    #define ROMANNUMERALS_H_INCLUDED
    #include <string>
    
    using namespace std;
    
    const int MAX_NUMS = 20;
    
    class RomanNumerals
    {
      private:
        string romanNums[MAX_NUMS];
    
      public:
        RomanNumerals()
        {
            string romanNums[MAX_NUMS] = {"I", "II", "III", "IV", "V", "VI", "VII", "VIII", "IX", "X", "XI", "XII", "XIII", "XIV", "XV", "XVI", "XVII", "XVIII", "XIX", "XX" };
        }
    
        string getRomanNumerals(int num)
        {
             return romanNums[num-1];
         }
    
    };
    
    #endif // ROMANNUMERALS_H_INCLUDED
    These are my warnings:
    [code
    C:\Users\Leonard\Desktop\New folder (2)\RomanNumerals.h||In constructor 'RomanNumerals::RomanNumerals()':|
    C:\Users\Leonard\Desktop\New folder (2)\RomanNumerals.h|17|warning: unused variable 'romanNums'|
    ||=== Build finished: 0 errors, 1 warnings ===|
    [/code]

    Which is really frustrating because if I put the array directly into my main.cpp and call it like I'm trying to here, it works perfectly. Is there some magical way to setup an array in a class or constructor? Argh!

  2. #2
    Registered User
    Join Date
    Jun 2005
    Posts
    6,815
    Your romanNums array inside the constructor is local to that constructor, and is not the same thing as the private member.

    Try this instead
    Code:
    RomanNumerals::RomanNumerals()
    {
            std::string romanNumsInitialiser[MAX_NUMS] = {"I", "II", "III", "IV", "V", "VI", "VII", "VIII", "IX", "X", "XI", "XII", "XIII", "XIV", "XV", "XVI", "XVII", "XVIII", "XIX", "XX" };
            std::copy(romanNumsInitialiser, romanNumsInitialiser + MAX_NUMS, romanNums);
    }
    The copy() algorithm is in the standard header <algorithms>.


    Also, NEVER place a "using namespace std;" directive in a header file. It is extremely bad practice, for many reasons that have been amply documented many times on this site and in many places on the internet. That means, if you want to use std::string in a header file, then refer to it as "std::string" not as "string".
    Right 98% of the time, and don't care about the other 3%.

    If I seem grumpy or unhelpful in reply to you, or tell you you need to demonstrate more effort before you can expect help, it is likely you deserve it. Suck it up, Buttercup, and read this, this, and this before posting again.

  3. #3
    - - - - - - - - oogabooga's Avatar
    Join Date
    Jan 2008
    Posts
    2,808
    Another possibility:
    Code:
    #ifndef ROMANNUMERALS_H_INCLUDED
    #define ROMANNUMERALS_H_INCLUDED
    #include <string>
    
    class RomanNumerals
    {
      private:
      static const int MAX_NUMS = 20;
      static const std::string romanNums[MAX_NUMS];
    
      public:
        RomanNumerals()
        {
        }
    
        std::string getRomanNumerals(int num)
        {
            return romanNums[num-1];
        }
    
    };
    
    #endif // ROMANNUMERALS_H_INCLUDED
    
    // Put this in the cpp file
    const std::string RomanNumerals::romanNums[MAX_NUMS] = {
          "I", "II", "III", "IV", "V", "VI", "VII", "VIII", "IX", "X",
          "XI", "XII", "XIII", "XIV", "XV", "XVI", "XVII", "XVIII", "XIX", "XX"
    };
    The cost of software maintenance increases with the square of the programmer's creativity. - Robert D. Bliss

  4. #4
    Registered User
    Join Date
    Mar 2005
    Posts
    37
    Quote Originally Posted by grumpy View Post
    Also, NEVER place a "using namespace std;" directive in a header file. It is extremely bad practice....
    Good to know, I kind of got that to work through trial and error (I'm all self taught from a few books atm, and they never really showed how to use strings the real way), and figured it was "cleaner" than using std:: all over the place for strings. I'll do some reading up on that and stop using the namespace in my headers, thanks for the tip.

    Its weird to me that I can declare an int variable inside my class definition, and then initalize it to say 5 inside my default constructor, but that "logic" doesn't translate over to an array. Having a hard time understanding why that doesn't work. Is it because the array itself is a collection of objects? or just how C++ treats arrays in regards to classes?

  5. #5
    Registered User
    Join Date
    Jun 2005
    Posts
    6,815
    Quote Originally Posted by Striph View Post
    Its weird to me that I can declare an int variable inside my class definition, and then initalize it to say 5 inside my default constructor, but that "logic" doesn't translate over to an array. Having a hard time understanding why that doesn't work. Is it because the array itself is a collection of objects? or just how C++ treats arrays in regards to classes?
    It is because the array is a collection of objects.
    Right 98% of the time, and don't care about the other 3%.

    If I seem grumpy or unhelpful in reply to you, or tell you you need to demonstrate more effort before you can expect help, it is likely you deserve it. Suck it up, Buttercup, and read this, this, and this before posting again.

  6. #6
    C++まいる!Cをこわせ!
    Join Date
    Oct 2007
    Location
    Inside my computer
    Posts
    24,654
    It does work. Unfortunately, Visual C++ does not support the required functionality yet.
    GCC does support it, so I'll show how:

    Code:
    #ifndef ROMANNUMERALS_H_INCLUDED
    #define ROMANNUMERALS_H_INCLUDED
    #include <string>
    #include <array>
     
    const int MAX_NUMS = 20;
     
    class RomanNumerals
    {
      private:
        std::array<std::string, MAX_NUMS> romanNums;
     
      public:
        RomanNumerals(): RomanNums({"I", "II", "III", "IV", "V", "VI", "VII", "VIII", "IX", "X", "XI", "XII", "XIII", "XIV", "XV", "XVI", "XVII", "XVIII", "XIX", "XX" })
        {
            
        }
     
        const std::string & getRomanNumerals(int num)
        {
             return romanNums.at(num-1);
         }
     
    };
     
    #endif // ROMANNUMERALS_H_INCLUDED
    Quote Originally Posted by Adak View Post
    io.h certainly IS included in some modern compilers. It is no longer part of the standard for C, but it is nevertheless, included in the very latest Pelles C versions.
    Quote Originally Posted by Salem View Post
    You mean it's included as a crutch to help ancient programmers limp along without them having to relearn too much.

    Outside of your DOS world, your header file is meaningless.

  7. #7
    Registered User
    Join Date
    Mar 2005
    Posts
    37
    Thanks Elysia, I've been meaning to load up Codeblocks on my system. Is there a "name" for what the ": RomanNums({...." after the RomanNumerals() constructor is called? Going to spend the weekend reading up on that, and namespace practices.

  8. #8
    C++まいる!Cをこわせ!
    Join Date
    Oct 2007
    Location
    Inside my computer
    Posts
    24,654
    It's called an initializer list.
    Quote Originally Posted by Adak View Post
    io.h certainly IS included in some modern compilers. It is no longer part of the standard for C, but it is nevertheless, included in the very latest Pelles C versions.
    Quote Originally Posted by Salem View Post
    You mean it's included as a crutch to help ancient programmers limp along without them having to relearn too much.

    Outside of your DOS world, your header file is meaningless.

  9. #9
    Registered User
    Join Date
    Jun 2005
    Posts
    6,815
    Note that initialiser lists are a feature of C++-11. There are advantages and disadvantages of using C++-11 features. The main disadvantage is that not all compilers support C++-11 features, except possibly as extensions, and support by some compilers is currently rather (for want of a better word) young.

    I am not seeking to discourage usage of C++-11 features. However, maturity of a language/library feature as well as maturity of available implementations, are valid considerations in deciding whether to use such features.
    Right 98% of the time, and don't care about the other 3%.

    If I seem grumpy or unhelpful in reply to you, or tell you you need to demonstrate more effort before you can expect help, it is likely you deserve it. Suck it up, Buttercup, and read this, this, and this before posting again.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Creating an array of object w/no default constructor
    By Angus in forum C++ Programming
    Replies: 28
    Last Post: 05-06-2009, 05:10 PM
  2. Replies: 6
    Last Post: 07-29-2008, 04:37 AM
  3. Creating array of objects w/o default constructor
    By QuestionC in forum C++ Programming
    Replies: 19
    Last Post: 05-02-2007, 08:03 PM
  4. Replies: 2
    Last Post: 04-04-2007, 06:34 PM
  5. template class default constructor problem
    By kocika73 in forum C++ Programming
    Replies: 3
    Last Post: 04-22-2006, 09:42 PM