class initialized array

Discussion in 'C++' started by Gary Wessle, Nov 8, 2006.

  1. Gary Wessle

    Gary Wessle Guest

    Hi

    how can I initialize a const char* myarr[] in a class constructor?

    class Myclass {
    const char* myarr[] = { "abc", "def" };
    ....
    };


    Myclass::Myclass():
    myarr[]( ??? )
    {}

    thanks
     
    Gary Wessle, Nov 8, 2006
    #1
    1. Advertising

  2. Gary Wessle wrote:
    > how can I initialize a const char* myarr[] in a class constructor?


    You cannot. Nobody can. No way to do that.

    V
    --
    Please remove capital 'A's when replying by e-mail
    I do not respond to top-posted replies, please don't ask
     
    Victor Bazarov, Nov 8, 2006
    #2
    1. Advertising

  3. Gary Wessle

    XtremDev Guest

    You need to add the static keyword.

    class MyClass
    {
    public:

    MyClass(){}
    ~MyClass(){}

    static const char * myarr[];
    };

    const char * MyClass::myarr[] = {"abc", "def" };
     
    XtremDev, Nov 8, 2006
    #3
  4. Gary Wessle

    mlimber Guest

    Gary Wessle wrote:
    > how can I initialize a const char* myarr[] in a class constructor?
    >
    > class Myclass {
    > const char* myarr[] = { "abc", "def" };
    > ...
    > };
    >
    >
    > Myclass::Myclass():
    > myarr[]( ??? )
    > {}


    Use a vector of strings rather than an array of char pointers
    (http://www.parashift.com/c -faq-lite/containers.html#faq-34.1), and
    then use an initializer helper class:

    template<typename T>
    class Initializer
    {
    vector<T> v_;
    public:
    Initializer( size_t reserveSize=0 ) { v_.reserve( reserveSize ); }
    Initializer& Add( const T& t ) { v_.push_back(t); return *this; }
    operator vector<T>() const { return v_; }
    };

    class Myclass {
    const vector<string> myarr;
    public:
    Myclass()
    : myarr( Initializer( 2 )
    .Add( "abc" )
    .Add( "def" ) )
    {}
    };

    Cheers! --M
     
    mlimber, Nov 8, 2006
    #4
  5. Gary Wessle

    mlimber Guest

    XtremDev wrote:
    > You need to add the static keyword.
    >
    > class MyClass
    > {
    > public:
    >
    > MyClass(){}
    > ~MyClass(){}
    >
    > static const char * myarr[];
    > };
    >
    > const char * MyClass::myarr[] = {"abc", "def" };


    What if it's not static data?

    Cheers! --M
     
    mlimber, Nov 8, 2006
    #5
  6. Gary Wessle

    XtremDev Guest

    mlimber a écrit :
    >
    > What if it's not static data?
    >
    > Cheers! --M


    your solution ;o)
     
    XtremDev, Nov 8, 2006
    #6
  7. Gary Wessle wrote:
    > ...
    > how can I initialize a const char* myarr[] in a class constructor?
    >
    > class Myclass {
    > const char* myarr[] = { "abc", "def" };
    > ...
    > };
    >
    >
    > Myclass::Myclass():
    > myarr[]( ??? )
    > {}
    > ...


    In this context arrays support only one initializer syntax: '()'-initializer,
    which leads to zero-initialization.

    In your case one way around is to declare the array with explicitly specified size

    class Myclass {
    const char* myarr[2];
    ...
    };

    and use assignment instead of initialization

    Myclass::Myclass()
    {
    myarr[0] = "abc";
    myarr[1] = "def";
    }

    --
    Best regards,
    Andrey Tarasevich
     
    Andrey Tarasevich, Nov 8, 2006
    #7
  8. Gary Wessle

    mlimber Guest

    Andrey Tarasevich wrote:
    > Gary Wessle wrote:
    > > ...
    > > how can I initialize a const char* myarr[] in a class constructor?
    > >
    > > class Myclass {
    > > const char* myarr[] = { "abc", "def" };
    > > ...
    > > };
    > >
    > >
    > > Myclass::Myclass():
    > > myarr[]( ??? )
    > > {}
    > > ...

    >
    > In this context arrays support only one initializer syntax: '()'-initializer,
    > which leads to zero-initialization.
    >
    > In your case one way around is to declare the array with explicitly specified size
    >
    > class Myclass {
    > const char* myarr[2];
    > ...
    > };
    >
    > and use assignment instead of initialization
    >
    > Myclass::Myclass()
    > {
    > myarr[0] = "abc";
    > myarr[1] = "def";
    > }


    Right, although probably the pointers should almost certainly be const
    also
    (http://www.parashift.com/c -faq-lite/const-correctness.html#faq-18.1),
    which would eliminate this possibility.

    Cheers! --M
     
    mlimber, Nov 8, 2006
    #8
  9. mlimber wrote:
    >> ...
    >> and use assignment instead of initialization
    >>
    >> Myclass::Myclass()
    >> {
    >> myarr[0] = "abc";
    >> myarr[1] = "def";
    >> }

    >
    > Right, although probably the pointers should almost certainly be const
    > also
    > ...


    That's something only the OP knows.

    --
    Best regards,
    Andrey Tarasevich
     
    Andrey Tarasevich, Nov 8, 2006
    #9
  10. Gary Wessle

    Salt_Peter Guest

    Gary Wessle wrote:
    > Hi
    >
    > how can I initialize a const char* myarr[] in a class constructor?
    >
    > class Myclass {
    > const char* myarr[] = { "abc", "def" };
    > ...
    > };
    >
    >
    > Myclass::Myclass():
    > myarr[]( ??? )
    > {}
    >
    > thanks


    You could deal with allocating a pointer in the ctor body.
    But thats old school stuff and frankly: much more work and way too
    fragile.
    You can only initialize an array with default values.
    example:

    template< typename T, const size_t Size >
    MyClass
    {
    T array[ Size ];
    MyClass() : array() { } // init elements to
    // whatever the default T() might be
    };

    A std::string doesn't suffer from that handicap.

    #include <iostream>
    #include <ostream>
    #include <string>

    template < typename T >
    class MyClass
    {
    T m_t;
    public:
    MyClass(const T& t) : m_t(t) { }
    friend
    std::eek:stream&
    operator<<(std::eek:stream& os, const MyClass& r_my)
    {
    return os << r_my.m_t;
    }
    };

    int main()
    {
    MyClass< std::string > instance("abc def");
    std::cout << instance << std::endl; // so simple

    return 0;
    }
     
    Salt_Peter, Nov 8, 2006
    #10
  11. Gary Wessle

    Salt_Peter Guest

    XtremDev wrote:
    > You need to add the static keyword.
    >
    > class MyClass
    > {
    > public:
    >
    > MyClass(){}
    > ~MyClass(){}
    >
    > static const char * myarr[];
    > };
    >
    > const char * MyClass::myarr[] = {"abc", "def" };


    Static members are nearly never a "better" solution or even a solution
    at all.
    Specially when static members is not what is required.
    In this case, you have no choice but to provide static member functions
    to access the static member.
    Then there is the real showstopper for those of you that enjoy living
    in a static world:
    What's the "static initialization order fiasco"?
    http://www.parashift.com/c -faq-lite/ctors.html
    section 10.12

    The better solution in this case is std::strings or std::vector of
    strings.
     
    Salt_Peter, Nov 8, 2006
    #11
  12. Salt_Peter wrote:
    >> You need to add the static keyword.
    >>
    >> class MyClass
    >> {
    >> public:
    >>
    >> MyClass(){}
    >> ~MyClass(){}
    >>
    >> static const char * myarr[];
    >> };
    >>
    >> const char * MyClass::myarr[] = {"abc", "def" };

    >
    > Static members are nearly never a "better" solution or even a solution
    > at all.


    If the data in 'myarr' is not [potentially] specific to each instance of the
    class, then 'static' is not only a solution, but the best solution possible.
    Actually, it would be a design error not to use 'static' in that case.

    > Specially when static members is not what is required.


    That is the question only OP can answer.

    > In this case, you have no choice but to provide static member functions
    > to access the static member.


    Not necessarily. If depends heavily on what is the purpose of that member and
    how it is supposed to be used. That's another question only OP can answer.

    > Then there is the real showstopper for those of you that enjoy living
    > in a static world:
    > What's the "static initialization order fiasco"?
    > http://www.parashift.com/c -faq-lite/ctors.html
    > section 10.12


    That's a far cry from what we have in the OP's case. Almost unrelated. It's like
    saying "Don't use dynamic memory to store arrays of 'int's because one day
    you'll forget to declare some class's destructor as 'virtual'".

    > The better solution in this case is std::strings or std::vector of
    > strings.


    It depends on "what is required".

    --
    Best regards,
    Andrey Tarasevich
     
    Andrey Tarasevich, Nov 8, 2006
    #12
  13. Gary Wessle

    BobR Guest

    Salt_Peter wrote in message ...
    >
    >XtremDev wrote:
    >> You need to add the static keyword.
    >>
    >> class MyClass { public:
    >> MyClass(){}
    >> ~MyClass(){}
    >> static const char * myarr[];
    >> };
    >> const char * MyClass::myarr[] = {"abc", "def" };

    >



    >In this case, you have no choice but to provide static member functions
    >to access the static member.


    Is that statement backwards, or, is my compiler deprecated?
    'print()' is non-static, but, prints the (static) lines.

    class Examp{ public:
    Examp( int const n ) : index( n ){}
    Examp() : index( 0 ){}
    // ----------------------
    void print( std::eek:stream &out ) const {
    if( index < 0 || index > MaxLines - 1 ){
    out << lines[ 0 ];
    }
    else{
    out << lines[ index ];
    }
    return;
    } // print()
    //----------------------
    private:
    int index;
    static int const MaxLines = 4;
    static std::string const lines[ MaxLines ];
    }; //end class Examp
    // ------------------------------------
    // -- static --
    std::string const Examp::lines[ Examp::MaxLines ] = {
    "String 1.\n",
    "String 2.\n",
    "String 3.\n",
    "ERROR in indexing.\n"
    };
    // ------------------------------------

    int main(){
    Examp X(1);
    X.print( std::cout );
    }

    --
    Bob R
    POVrookie
     
    BobR, Nov 8, 2006
    #13
  14. Gary Wessle

    Salt_Peter Guest

    BobR wrote:
    > Salt_Peter wrote in message ...
    > >
    > >XtremDev wrote:
    > >> You need to add the static keyword.
    > >>
    > >> class MyClass { public:
    > >> MyClass(){}
    > >> ~MyClass(){}
    > >> static const char * myarr[];
    > >> };
    > >> const char * MyClass::myarr[] = {"abc", "def" };

    > >

    >
    >
    > >In this case, you have no choice but to provide static member functions
    > >to access the static member.

    >
    > Is that statement backwards, or, is my compiler deprecated?
    > 'print()' is non-static, but, prints the (static) lines.


    print() is const, static if you prefer

    >
    > class Examp{ public:
    > Examp( int const n ) : index( n ){}
    > Examp() : index( 0 ){}
    > // ----------------------
    > void print( std::eek:stream &out ) const {
    > if( index < 0 || index > MaxLines - 1 ){
    > out << lines[ 0 ];
    > }
    > else{
    > out << lines[ index ];
    > }
    > return;
    > } // print()
    > //----------------------
    > private:
    > int index;
    > static int const MaxLines = 4;
    > static std::string const lines[ MaxLines ];
    > }; //end class Examp
    > // ------------------------------------
    > // -- static --
    > std::string const Examp::lines[ Examp::MaxLines ] = {
    > "String 1.\n",
    > "String 2.\n",
    > "String 3.\n",
    > "ERROR in indexing.\n"
    > };
    > // ------------------------------------
    >
    > int main(){
    > Examp X(1);
    > X.print( std::cout );
    > }
    >
    > --
    > Bob R
    > POVrookie


    Why not...

    #include <iostream>
    #include <ostream>
    #include <vector>
    #include <string>
    #include <iterator>

    class Examp
    {
    std::vector< std::string > vs;
    public:
    Examp() : vs() { load(); }
    void load();
    /* friend */
    friend std::eek:stream&
    operator<<( std::eek:stream&, const Examp& );
    };

    void Examp::load()
    {
    vs.push_back( "String 0." );
    vs.push_back( "String 1." );
    vs.push_back( "String 2." );
    }

    std::eek:stream&
    operator<<( std::eek:stream& os, const Examp& r_x )
    {
    std::copy( r_x.vs.begin(),
    r_x.vs.end(),
    std::eek:stream_iterator
    < std::string >( os, "\n" ) );
    return os;
    }

    int main()
    {
    Examp examp;
    std::cout << examp;
    }

    It doesn't get any simpler.
    And you can make examp static for all i care.
     
    Salt_Peter, Nov 9, 2006
    #14
  15. Gary Wessle

    BobR Guest

    Salt_Peter wrote in message
    <>...
    >
    >BobR wrote:
    >> Salt_Peter wrote in message ...
    >>
    >> >In this case, you have no choice but to provide static member functions
    >> >to access the static member.

    >>
    >> Is that statement backwards, or, is my compiler deprecated?
    >> 'print()' is non-static, but, prints the (static) lines.

    >
    >print() is const, static if you prefer


    So? Remove the 'const', it still compiles and runs for me. What I was getting
    around to is, AFAIK, a non-static function can access static members, but, a
    static function can only access static data members and static functions.
    More below......

    >>
    >> class Examp{ public:
    >> Examp( int const n ) : index( n ){}
    >> Examp() : index( 0 ){}
    >> // ----------------------
    >> void print( std::eek:stream &out ) const {
    >> if( index < 0 || index > MaxLines - 1 ){
    >> out << lines[ 0 ];
    >> }
    >> else{ out << lines[ index ]; }
    >> return;
    >> } // print()
    >> //----------------------
    >> private:
    >> int index;
    >> static int const MaxLines = 4;
    >> static std::string const lines[ MaxLines ];
    >> }; //end class Examp
    >> // ------------------------------------
    >> // -- static --
    >> std::string const Examp::lines[ Examp::MaxLines ] = {
    >> "String 1.\n", "String 2.\n", "String 3.\n",
    >> "ERROR in indexing.\n"
    >> };
    >> // ------------------------------------
    >>
    >> int main(){
    >> Examp X(1);
    >> X.print( std::cout );
    >> }
    >>
    >> Bob R POVrookie

    >
    >Why not...
    >
    >#include <iostream>
    >#include <ostream>
    >#include <vector>
    >#include <string>
    >#include <iterator>
    >
    >class Examp {
    > std::vector< std::string > vs;
    >public:
    > Examp() : vs() { load(); }
    > void load();
    > /* friend */
    > friend std::eek:stream&
    > operator<<( std::eek:stream&, const Examp& );
    >};
    >
    >void Examp::load(){
    > vs.push_back( "String 0." );
    > vs.push_back( "String 1." );
    > vs.push_back( "String 2." );
    >}
    >
    >std::eek:stream&
    >operator<<( std::eek:stream& os, const Examp& r_x ){
    > std::copy( r_x.vs.begin(), r_x.vs.end(),
    > std::eek:stream_iterator< std::string >( os, "\n" ) );
    > return os;
    >}
    >
    >int main(){
    > Examp examp;
    > std::cout << examp;
    >}
    >
    >It doesn't get any simpler.
    >And you can make examp static for all i care.


    In my class, no matter how many objects of the class there are, those strings
    are never duplicated, there's just that one piece of storage. Remove the
    'const' on the strings and you could change them. Put them in 'public:' and
    you don't even need an instance of the class to access them (like: a global
    with a scope resolution operator / namespace).

    If you wanted different strings in each instance, your class would be the way
    to go.

    It comes down to how you want to use the class / data.

    Oh, almost forgot: My class is better than your class 'cause it uses two less
    header includes. <G>
    --
    Bob R
    POVrookie
     
    BobR, Nov 9, 2006
    #15
    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. Gernot Frisch

    const initialized array as argument?

    Gernot Frisch, Dec 16, 2004, in forum: C++
    Replies:
    9
    Views:
    409
    Thorsten Ottosen
    Dec 17, 2004
  2. Nishu

    partial initialized array

    Nishu, Nov 29, 2007, in forum: C Programming
    Replies:
    4
    Views:
    335
    Barry Schwarz
    Dec 1, 2007
  3. Peng Yu
    Replies:
    2
    Views:
    336
    Linlin Yan
    Sep 4, 2008
  4. arnuld
    Replies:
    5
    Views:
    3,828
    Barry Schwarz
    Jul 25, 2009
  5. afrenk123
    Replies:
    0
    Views:
    404
    afrenk123
    Oct 23, 2010
Loading...

Share This Page