У меня есть шаблон класса C ++, который делает массив указателей. Это также получает typedefed для создания Arrays of Arrays и так далее:
typedef Array<Elem> ElemArray;
typedef Array<ElemArray> ElemArrayArray;
typedef Array<ElemArrayArray> ElemArrayArrayArray;
Я хотел бы иметь возможность установить один листовой узел из другого, скопировав указатель, чтобы они оба ссылались на один и тот же элемент.
Но я также хочу иметь возможность установить один массив (или массив массивов и т. Д.) Из другого. В этом случае я не хочу копировать указатели, я хочу держать массивы отдельно и опускаться в каждый из них, пока не доберусь до конечного узла, где я, наконец, скопирую указатели.
У меня есть код, который делает это (ниже). Когда вы устанавливаете что-либо в массиве, он вызывает метод CopyIn для копирования.
Но так как это шаблонно, ему также нужно вызвать метод CopyIn в листовом классе, что означает, что я должен добавить фиктивный метод в каждый листовой класс, который просто возвращает false.
Я также попытался добавить флаг в шаблон, чтобы сообщить ему, содержит ли он массивы или нет, и, таким образом, вызывать ли метод CopyIn. Это работает отлично - метод CopyIn конечных узлов никогда не вызывается, но он все еще должен быть там, чтобы компиляция работала!
Есть ли лучший способ сделать это?
#include <stdio.h>
class Elem {
public:
Elem(int v) : mI(v) {}
void Print() { printf("%d\n",mI); }
bool CopyIn(Elem *v) { return false; }
int mI;
};
template < typename T > class Array {
public:
Array(int size) : mB(0), mN(size) {
mB = new T* [size];
for (int i=0; i<mN; i++)
mB[i] = new T(mN);
}
~Array() {
for (int i=0; i<mN; i++)
delete mB[i];
delete [] mB;
}
T* Get(int i) { return mB[i]; }
void Set(int i, T* v) {
if (! mB[i]->CopyIn(v) ) {
// its not an array, so copy the pointer
mB[i] = v;
}
}
bool CopyIn(Array<T>* v) {
for (int i=0; i<mN; i++) {
if (v && i < v->mN ) {
if ( ! mB[i]->CopyIn( v->mB[i] )) {
// its not an array, so copy the pointer
mB[i] = v->mB[i];
}
}
else {
mB[i] = 0;
}
}
return true; // we did the copy, no need to copy pointer
}
void Print() {
for (int i=0; i<mN; i++) {
printf("[%d] ",i);
mB[i]->Print();
}
}
private:
T **mB;
int mN;
};
typedef Array<Elem> ElemArray;
typedef Array<ElemArray> ElemArrayArray;
typedef Array<ElemArrayArray> ElemArrayArrayArray;
int main () {
ElemArrayArrayArray* a = new ElemArrayArrayArray(2);
ElemArrayArrayArray* b = new ElemArrayArrayArray(3);
// In this case I need to copy the pointer to the Elem into the ElemArrayArray
a->Get(0)->Get(0)->Set(0, b->Get(0)->Get(0)->Get(0));
// in this case I need go down through a and b until I get the to Elems
// so I can copy the pointers
a->Set(1,b->Get(2));
b->Get(0)->Get(0)->Get(0)->mI = 42; // this will also set a[0,0,0]
b->Get(2)->Get(1)->Get(1)->mI = 96; // this will also set a[1,1,1]
// should be 42,2, 2,2, 3,3, 3,96
a->Print();
}