I wanted to create a template <typename T> class InitConst
some of whose members are arrays of T
. I wanted to populate these arrays during the class' objects initialization and then be sure that these arrays would not change anymore, so I defined a member const T* const v
for each such array (I know that the first const refers to the elements and the second to the pointers).
Experimenting with this made me conclude that defining "v" to be "const pointer to const" obliged me to allocate and populate the corresponding array before finally initializing "v" with the address of this array. Moreover, since I cannot initialize "v" inside the body of the constructor of class "InitConst", I concluded that I needed an auxiliary function, whose role was to (a) get the constructors arguments, (b) allocate and populate the arrays, and (c) use some static pointers to hold the addresses of these arrays. These static pointers would finally be used by the constructor to initialize the const pointers, so I got a code like this:
template <typename T>
class InitConst
{
public:
const T* const v1;
const T* const v2;
const T* const v3;
InitConst(T a1, T a2, T a3, int n)
: v1( init(a1,a2,a3,n) ), v2(init_p.temp_v2), v3(init_p.temp_v3)
{ }
private:
struct Tinit {
T* temp_v1;
T* temp_v2;
T* temp_v3;
};
static Tinit init_p;
T* init (T a1, T a2, T a3, int n)
{
init_p.temp_v1 = new T[n];
init_p.temp_v2 = new T[n];
init_p.temp_v3 = new T[n];
// populate "temp_v1", "temp_v2" and "temp_v3" using the method's arguments.
return init_p.temp_v1;
} // End method init.
}; // End class InitConst.
template <typename T>
typename InitConst<T>::Tinit InitConst<T>::init_p;
This code compiles and works as expected, but I consider this design contorted: I am used to simple code, where I first allocate an array, then compute its elements (both things usually happen in the constructor's body) and then use the array. Above, in contrast, the constructor does almost nothing by itself: its role is transferred to method "init", which actually creates the arrays and uses some auxiliary pointers to communicate them back to the constructor.
I then wonder:
a) Is this design (or something similar) necessary if I decide do declare each pointer as "const pointer to const", or there is a cleaner way to do it?
b) Declaring each pointer as "const pointer to const" was a way to protect against misuses of the class, but perhaps I do not need that much. A somewhat less strict approach would have been to declare "v1" and its siblings as private members, so that they could not be changed from outside of the class. However, doing so would also prevent them from being read from outside of the class, and I do not want to have a "read_vx" method for each array "vx". What could I then do about it, that is, what approach would lead to a more readable code and still guarantee at least that the arrays cannot be changed from outside of the class?
Thanks in advance, and sorry for the long prose.
Edit: as I commented below, in my real code, the various arrays that I want to compute are much more efficiently computed all together, and that is why I use a single "init" function. The arguments to "init" ("a1", "a2", "a3") that I supplied in the example were actually misleading.