-
August 2nd, 2008, 08:52 AM
#1
Initializing an array data member?
Hi,
Let's take a class A
Code:
class A
{
char a[10];
public:
A(char *);
};
so..once I have this class with a constructor that accepts a char *, can I do this..?
Code:
A::A(char * s)
:a(s){}
if not, it will mean that a array member can never be initialized using the member initialization list. or is it not?
will be elated to get the right "pointer". ( :-D )
Indrajit
-
August 2nd, 2008, 08:57 AM
#2
Re: Initializing an array data member?
Originally Posted by indrajit_p1
Hi,
Let's take a class A
Code:
class A
{
char a[10];
public:
A(char *);
};
so..once I have this class with a constructor that accepts a char *, can I do this..?
Code:
A::A(char * s)
:a(s){}
if not, it will mean that a array member can never be initialized using the member initialization list. or is it not?
will be elated to get the right "pointer". ( :-D )
Indrajit
I know literally nothing about initialising arrays in a initialiser list but if you actually compiled the code you'd get an error similiar to this:
Code:
error C2536: 'A::A::a' : cannot specify explicit initializer for arrays
-
August 3rd, 2008, 03:36 AM
#3
Re: Initializing an array data member?
hmm...
I started in programming with Fortran and moved on to C. Always felt in those days that C++ is not really as good as it looks like.
But the last 4/5 years on and off with C++ had the idea that all the fancy features of C++ fits into each other amazingly well, growing in me.
Now it looks to me like they should have stopped at dumb C data strucutres where you could simply use a initializer list.
"Seem"s like I have come a full circle...
:-)
I
p.s.: MyBowlCut - thanks for the very conclusive pointer though.. (a word better than coclusive is evading me as I write this)
Last edited by indrajit_p1; August 3rd, 2008 at 03:39 AM.
-
August 3rd, 2008, 03:23 PM
#4
Re: Initializing an array data member?
most likely you should not be using c-style arrays at all.
If you are trying to represent a string, use std::string.
If you are trying to represent a buffer, use std::vector.
Trying to bring the habits you have learned in C to C++ will result in very bad C++ code.
Last edited by souldog; August 3rd, 2008 at 03:26 PM.
Wakeup in the morning and kick the day in the teeth!! Or something like that.
"i don't want to write leak free code or most efficient code, like others traditional (so called expert) coders do."
-
August 3rd, 2008, 04:01 PM
#5
Re: Initializing an array data member?
Originally Posted by indrajit_p1
Now it looks to me like they should have stopped at dumb C data strucutres where you could simply use a initializer list.
And what would happen, if s points to more than 10 characters? Should a be initialized with the first 10 characters only? Or should a be initialized with the first 9 characters only and a[9] be automatically initialized with a terminating zero. Or should more than 10 characters be copied causing a buffer overflow that some distant day would have crashed the program?
There are good reasons why the code you posted does not compile.
More computing sins are committed in the name of efficiency (without necessarily achieving it) than for any other single reason - including blind stupidity. --W.A.Wulf
Premature optimization is the root of all evil --Donald E. Knuth
Please read Information on posting before posting, especially the info on using [code] tags.
-
August 3rd, 2008, 05:03 PM
#6
Re: Initializing an array data member?
Frankly, it *should* be possible to do something like
Code:
class A
{
char a[10];
public:
A(): a({0,1,2,3,4,5,6,7,8,9})
{}
};
though. That would make sense, and is a fairly strange oversight.
-
August 3rd, 2008, 05:22 PM
#7
Re: Initializing an array data member?
Originally Posted by Lindley
Frankly, it *should* be possible to do something like
Code:
class A
{
char a[10];
public:
A(): a({0,1,2,3,4,5,6,7,8,9})
{}
};
though. That would make sense, and is a fairly strange oversight.
I agree with that.
-
August 3rd, 2008, 08:33 PM
#8
Re: Initializing an array data member?
Hi guys,
This really made me appreciate std::string!
However,
I did some studying of my own and I came to a conclusion at this point that it is not possible to initialize an array in the initializer list and I'd like to confirm this finding (or correct) by those who know better.
My understanding is this -
When an element initializer is used, its copy constructor is called,
I'm not sure if this applies to an array but it certainly applies to sequential containers.
if this too applies to the array, and we know that there is no array copy or assignment,
hence, the initialization would fail for the array.
can anyone tell me more in details if this is true or not?
Thanks.
-
August 3rd, 2008, 09:03 PM
#9
Re: Initializing an array data member?
Not always the copy constructor; but a constructor of some type, certainly. Since arrays aren't constructable....
-
August 4th, 2008, 12:41 AM
#10
Re: Initializing an array data member?
looks like a new language feature, std::initializer_list, will be introduced to solve this problem.
Wakeup in the morning and kick the day in the teeth!! Or something like that.
"i don't want to write leak free code or most efficient code, like others traditional (so called expert) coders do."
-
August 4th, 2008, 04:05 AM
#11
Re: Initializing an array data member?
Hmm...
This is turning interesting and educating.
Lindley, your suggestion hardcodes the initializer list into the constructor. (??)
Indrajit
-
August 4th, 2008, 05:07 AM
#12
Re: Initializing an array data member?
Lindley's example is not valid in C++. It appears that it will be in future implementations of the language.
Depending on what you are using that c-style array for, C++ most likely provides more appropriate tools, such as std::string, std::vector, ....
If you must use a c-style array, then the normal way to initialize it is in the body of the constructor, not in the initializer list.
Last edited by souldog; August 4th, 2008 at 05:09 AM.
Wakeup in the morning and kick the day in the teeth!! Or something like that.
"i don't want to write leak free code or most efficient code, like others traditional (so called expert) coders do."
-
August 4th, 2008, 05:46 AM
#13
Re: Initializing an array data member?
As long as I can think of, using C-style arrays is cheaper than using std::vector or std::string. I've made a template class for static arrays which is essentially the same with C-style arrays except they are more convenient. I'm posting it as I think it might help you.
Code:
template <class Type, size_t Length>
struct static_array
{
Type Data[Length];
operator Type* ()
{ return Data; }
operator Type const* () const
{ return Data; }
typedef static_array<Type, Length> my_type;
static_array() {}
static_array( Type const* pData )
{
for( size_t i = 0; i < Length; i ++ )
Data[i] = pData[i]; // <-- introduces inefficiency
}
static_array( my_type const& Ob )
{
for( size_t i = 0; i < Length; i ++ )
Data[i] = Ob.Data[i];
}
my_type& operator = ( my_type const& Ob )
{
for( size_t i = 0; i < Length; i ++ )
Data[i] = Ob.Data[i];
return *this;
}
~static_array() {}
};
// You can specify constructor for it.
class A
{
static_array<char, 10> a;
public:
A(char * p)
: a(p)
{}
};
But there is a problem. Each member in the array must be default-initialized first and then assigned to a value (see the tagged line above). A more sophisticated version can fix this problem.
Code:
// This struct is used to call constructor / destructor in demand
template <class Type>
struct manual_construct
{
Type data;
// Construction / Destruction
manual_construct()
{}
manual_construct( Type const& Ob )
: data(Ob)
{}
~manual_construct()
{}
// Operator new / delete
// These operators does nothing.
void* operator new ( size_t, void* pvAddress )
{ return pvAddress; }
void operator delete( void*, void* )
{}
void operator delete( void* )
{}
};
// This class takes space for one element, but construction will be done
// in demand
template <class Type>
class reserved_space
{
private:
char buffer[sizeof (Type)]; // declared as char array to prevent calling constructor automatically
public:
void construct()
{ new (buffer) manual_construct<Type>(); }
void construct( Type const& Ob )
{ new (buffer) manual_construct<Type>( Ob ); }
void destruct()
{ delete reinterpret_cast<manual_construct<Type>*>( buffer ); }
reserved_space() {}
~reserved_space() {}
};
//
template <class Type, size_t Length>
struct static_array
{
reserved_space<Type> data[Length];
operator Type* ()
{ return reinterpret_cast<Type*>(data); }
operator Type const* () const
{ return reinterpret_cast<Type const*>(data); }
typedef static_array<Type, Length> my_type;
static_array()
{
for( size_t i = 0; i < Length; i ++ )
data[i].construct();
}
static_array( Type const* pData )
{
for( size_t i = 0; i < Length; i ++ )
data[i].construct( pData[i] );
}
static_array( my_type const& Ob )
{
for( size_t i = 0; i < Length; i ++ )
data[i].construct( Ob[i] );
}
my_type& operator = ( my_type const& Ob )
{
for( size_t i = 0; i < Length; i ++ )
(*this)[i] = Ob[i];
return *this;
}
~static_array()
{
for( size_t i = 0; i < Length; i ++ )
data[i].destruct();
}
};
Sorry if too complex. Some other people may have simpler solution.
I'd really be happy if C++ had template typedefs and void references, like void& / void const&.
When I program, I type, type, type... and eventually delete everything as my code contains buckets of bugs.
OMG so I'm programming to make bugs?
I'm happy when I meet someone who doesn't agree with me, because I can learn a lot by talking to him/her.
"Genius is one percent inspiration and ninety-nine percent perspiration." Thomas Edison
-
August 4th, 2008, 06:06 AM
#14
Re: Initializing an array data member?
Wakeup in the morning and kick the day in the teeth!! Or something like that.
"i don't want to write leak free code or most efficient code, like others traditional (so called expert) coders do."
-
August 4th, 2008, 06:59 AM
#15
Re: Initializing an array data member?
I've looked at the boost source code and found that boost::array has the same problem. e.g. all elements are first initialized and then can be assigned. So it might not optimal when elements are heavy objects. (umm...maybe swap() can help but not entirely)
How about re-implementing that? We can invoke copy constructors directly.
Hope your opinions
I'd really be happy if C++ had template typedefs and void references, like void& / void const&.
When I program, I type, type, type... and eventually delete everything as my code contains buckets of bugs.
OMG so I'm programming to make bugs?
I'm happy when I meet someone who doesn't agree with me, because I can learn a lot by talking to him/her.
"Genius is one percent inspiration and ninety-nine percent perspiration." Thomas Edison
Posting Permissions
- You may not post new threads
- You may not post replies
- You may not post attachments
- You may not edit your posts
-
Forum Rules
|
Click Here to Expand Forum to Full Width
|