Если эффективность не является одной из ваших основных целей, вы можете
- Заблокировать прямой доступ к
m_arr
, сделав его приватным
- добавить массив bool того же размера, что и m_arr
m_field_initialized = new bool[n]
и инициализировать его ложными значениями.
- Создание открытого (или защищенного) экземпляра класса средства доступа, который будет переносить
m_arr
и m_field_initialized
- Метод доступа должен иметь метод
setVal(int i, double val)
, который установит m_arr[i]
и дополнительно m_field_initialized[i]
флаг true
;
- В вашем тесте метода проверки инициализации, если все поля
m_field_initialized
были установлены в true.
Вы можете улучшить это, предоставив метод для более быстрого прямого доступа, когда были выполнены условия инициализации. Он должен вернуть нулевой указатель до проверки инициализации, а после успешной инициализации он вернет указатель вашего массива.
double * directAccess() {
if (m_arr_initialized) return m_arr;
else return 0;
}
m_arr_initialized
устанавливается вашим методом проверки инициализации.
Если для размещения массива в базовом классе не требуется, вы можете установить m_arr
в ноль, оставить выделение для подклассов и просто проверить, был ли указатель m_arr
установлен в ненулевое значение. Дополнительно может быть установлено действительное поле, обозначающее выделенный размер. Или вы можете как ранее заблокировать доступ к m_arr и предоставить метод в базовом классе для выделения allocate(std::size_t size)
, или выделения с начальным значением allocate(std::size_t size, double initVal)
, или даже принудительно передать функцию инициализации allocate(std::size_t size, double (*callback)(std::size_t element))
, которая будет вызываться для каждого элемента. Есть много возможностей.
edit: после вашего редактирования я предлагаю указатель (или ссылку) либо на объект инициализации, либо на обратный вызов функции в конструкторе BaseClass. Это заставит подклассы предоставлять код инициализации. Учтите следующее:
class InitializerInterface
{
public:
virtual double get(int element) const = 0;
}
В вашем конструкторе базового класса
BaseClass(int n, const InitializerInterface & initializer) {
m_arr = new double[n];
size = n;
for (int i = 0; i < n; i++)
m_arr[i] = initializer.get(i);
};
Теперь любой подкласс должен передать некоторую инициализацию конструктору. Конечно, вы можете заменить метод get () на функтор или добавить поддержку функции обратного вызова. Это зависит от ваших предпочтений.
// последнее редактирование, чтобы сделать его корректным