By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
446,227 Members | 1,290 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 446,227 IT Pros & Developers. It's quick & easy.

class initialized array

P: n/a
Hi

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

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

thanks
Nov 8 '06 #1
Share this Question
Share on Google+
14 Replies


P: n/a
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
Nov 8 '06 #2

P: n/a
You need to add the static keyword.

class MyClass
{
public:

MyClass(){}
~MyClass(){}

static const char * myarr[];
};

const char * MyClass::myarr[] = {"abc", "def" };

Nov 8 '06 #3

P: n/a
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-lit...html#faq-34.1), and
then use an initializer helper class:

template<typename T>
class Initializer
{
vector<Tv_;
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<stringmyarr;
public:
Myclass()
: myarr( Initializer( 2 )
.Add( "abc" )
.Add( "def" ) )
{}
};

Cheers! --M

Nov 8 '06 #4

P: n/a
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

Nov 8 '06 #5

P: n/a

mlimber a écrit :

What if it's not static data?

Cheers! --M
your solution ;o)

Nov 8 '06 #6

P: n/a
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
Nov 8 '06 #7

P: n/a
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-lit...html#faq-18.1),
which would eliminate this possibility.

Cheers! --M

Nov 8 '06 #8

P: n/a
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
Nov 8 '06 #9

P: n/a

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::ostream&
operator<<(std::ostream& 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;
}

Nov 8 '06 #10

P: n/a

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.

Nov 8 '06 #11

P: n/a
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
Nov 8 '06 #12

P: n/a

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::ostream &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
Nov 8 '06 #13

P: n/a

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::ostream &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::ostream&
operator<<( std::ostream&, const Examp& );
};

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

std::ostream&
operator<<( std::ostream& os, const Examp& r_x )
{
std::copy( r_x.vs.begin(),
r_x.vs.end(),
std::ostream_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.

Nov 9 '06 #14

P: n/a

Salt_Peter wrote in message
<11**********************@f16g2000cwb.googlegroups .com>...
>
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::ostream &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::ostream&
operator<<( std::ostream&, const Examp& );
};

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

std::ostream&
operator<<( std::ostream& os, const Examp& r_x ){
std::copy( r_x.vs.begin(), r_x.vs.end(),
std::ostream_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
Nov 9 '06 #15

This discussion thread is closed

Replies have been disabled for this discussion.