C++: static initialize an array member, member at a time
I now I can do this in global scope and everything works fine:
const char* Foo::bars[3] = {"a", "b", "c"};
But I want to do this because this is much more clearer and self documenting (especially if you use Enums as the index):
const char* Foo::bars[3];
bars[0] = "a";
bars[1] = "b";
bars[2] = "c";
Is it anyway possible?
I know I can do this inside a function (fo开发者_开发百科r example, the class's constructor) but what if the constructor is not called in the start of the program and I want to use the static array? That leads to problems.
How about this?
const char* Foo::bars[3] = {
/* Index Value */
/* 0 */ "a",
/* 1 */ "b",
/* 2 */ "c"
};
I often use this "technique" to make the initialization of arrays of structs look like a self-documenting spreadsheet.
In C++ there is no equivalent of the static
Java block.
If you really want to initialize the array automatically, you can create a simple class to do the job:
// in .cpp
class FooInitializer {
public:
FooInitializer() {
Foo:bars[0] = "a";
Foo:bars[1] = "b";
Foo:bars[2] = "c";
}
};
static FooInitializer fooInitializer;
You can use an accessor-function:
const char* GetArray()
{
static char* result[3];
static isInitialized = false;
if (!isInitialized)
{
result[0] = "a";
result[1] = "b";
result[3] = "c";
initialized=true;
}
return result;
}
Here's another solution that uses the Singleton pattern. Note that the array is initialized once in the singleton's constructor. Also note that this is not thread-safe. Also beware of the evilness of singletons (search this site for "singleton" to find some interesting debate on this matter).
#include <iostream>
class StringTable
{
public:
enum StringId
{
hello,
bye,
goodDay,
stringCount
};
static const char* lookup(StringId id) {return instance().table_[id];}
private:
StringTable()
{
table_[hello] = "Hello World!\n";
table_[bye] = "Goobye, cruel world!\n";
table_[goodDay] = "I said good day!\n";
}
static StringTable& instance()
{
static StringTable theInstance;
return theInstance;
}
const char* table_[stringCount];
};
int main()
{
std::cout << StringTable::lookup(StringTable::hello)
<< StringTable::lookup(StringTable::bye)
<< StringTable::lookup(StringTable::goodDay);
}
You probably want an extra const in bars
const char* const Foo::bars[3] =
{
"a",
"b",
"c"
};
The way you declared it, you can actually do what you wanted in setting the members one at a time, although you'd use an "init" function to do it.
If you do want it const, which is probably preferable, it will subsequently become illegal to assign them a line at a time, even in some kind of "init" method and you should simply use a code layout to make it clearer what you are doing.
精彩评论