Этот вопрос, вероятно, должен быть в Code Review , а не здесь.Но некоторые вещи в дизайне:
Обычно не рекомендуется управлять памятью вручную, предпочтительнее использовать существующие контейнеры вместо динамически размещаемых массивов.Тот факт, что конструктор получает право владения переданным указателем, не является распространенным и может привести к проблемам с пользовательским кодом.В настоящее время вы запрещаете некоторые виды использования, например:
int dims[3] = { 3, 4, 5 };
XArray array( 3, dims ); // or use sizeof(dims)/sizeof(dims[0]), or other trickery
Что проще для пользовательского кода, чем:
int ndims = 5;
int *dims = new int[ndims]
XArray array( ndims, dims );
Это также означает, что пользователь должен знать, что владение dims
имеети что они не могут delete
указатель.
Внутренне я бы использовал std::vector
для поддержки динамической памяти, поскольку это даст вам правильную семантику бесплатно.Так как это вам нужно реализовать конструктор копирования и оператор присваивания (или отключить их), так как текущий код не будет течь, но может попытаться удвоить часть памяти.Запомните правило трех: если вы предоставляете любой из конструктор копирования , оператор присваивания или деструктор , вам, вероятно, следует предоставить все три.
Ваша operator*
и operator+
утечка памяти (сам объект XArray
, поскольку внутренняя память фактически обрабатывается из-за отсутствия конструктора копирования, но не думайте, что это не причиначтобы создать конструктор копирования, вы, напротив, должны создать его)
Бросок char*
разрешен, но я бы порекомендовал вам этого не делать по разным причинам.Тип исключения должен содержать информацию о том, что произошло, иначе ваш код пользователя должен будет проанализировать содержимое исключения, чтобы определить, что пошло не так.Даже если вы решите использовать один тип, обратите внимание, что те же правила, которые используются при разрешении перегрузки, не применяются при обработке исключений, и, в частности, у вас могут возникнуть проблемы с отсутствующими преобразованиями.Это также еще один потенциал для утечки памяти в вашем проекте, так как при создании указателя на динамически выделяемую память вы делегируете ответственность за освобождение памяти вашим пользователям, если пользователь не освобождает память или пользователь на самом деле этого не делает.позаботьтесь об исключении и просто перехватите все (catch (...) {}
), вы потеряете ошибки.
Возможно, будет лучше, если вместо throw
ing вас assert
ed, если это возможно в вашей программе (это дизайнерское решение: насколько плох неправильный размер, что может случиться, даже если оно исключительное, или что не должно происходить?).
Член index_helper
не принадлежит классу, этоэто деталь реализации, которая используется только различными operator()
и get_helper()
методами, вы должны удалить его из класса, и вы можете распределить его статически в каждом operator()
.Также немного странно, что вы предлагаете отдельные operator()
для 1, 2 и 3 измерений, в то время как код является общим для обработки любых измерений, а также что вы фактически требуете от пользователя * знайте , что из общедоступного интерфейса две операции запрещены, что тоже не очень удачно.