Как я могу расширить класс в такой библиотеке, как Armadillo?

Я работаю с 3D-векторами для 3D-графики. Я создал класс vec3 для добавления таких функций, как getX, getY, getZ, setX, setY, setZ, setXYZ ... и так далее.

#include <armadillo>
using namespace arma;

// An extension to VEC class for Armadillo for 3D graphics.
class vec3 : public vec
{
public:

    // Constructor inits vector to 0,0,0
    vec3() : vec(3,fill::zeros) {}
    ~vec3(void){};

    double getX() const { return at(0); }
    double getY() const { return at(1); }
    double getZ() const { return at(2); }

    void   setX(double x){ ?????? = x; }
};

Я потерялся в очень необычной ситуации, которую никогда не обнаруживал:

Как использовать (i) доступ к элементам ... внутри класса?

Для функции получения, как видите, это просто, поскольку у нас есть, по крайней мере, функция "at". Но как мне создать функцию setX, которая вставляет в позицию 0 вектора данный элемент ...

Я пробовал это (i), явно не сработало. Я чувствую себя здесь таким новичком ... Где построен "век" ?. Std :: vector? ... Правильно ли я поступаю, выполняя эти простые вещи?


person Darkgaze    schedule 18.01.2014    source источник
comment
Я недостаточно знаю базовый класс (vec), чтобы ответить на ваш вопрос. Является ли код базового класса общедоступным? Можете ли вы опубликовать хотя бы публичный заголовок?   -  person Steven Hansen    schedule 19.01.2014
comment
Да, я подумал об этом. Думаю, тогда мне следует использовать базовый класс ... не так ли ?. Если бы это был std :: vector ... что мне тогда делать? Дай мне проверить.   -  person Darkgaze    schedule 19.01.2014
comment
Какая библиотека - броненосец? Это это?   -  person Gasim    schedule 19.01.2014
comment
@StevenHansen Это открытый исходный код. Я открыл включаемый файл, который перенаправляет на все файлы (я не нахожу VEC ... к сожалению), но увидел, что он включает: #include ‹vector› Сверху. Я предполагаю, что это связано с std: Тогда как мне это сделать внутри, если VEC сам является вектором шаблона?   -  person Darkgaze    schedule 19.01.2014
comment
Что ж, если базовым классом является stl :: vector, и если x является первым элементом, тогда это будет this[0]=x. Не видя исходного кода, может быть проще использовать композицию вместо наследования. (Имеет вместо Is a).   -  person Steven Hansen    schedule 19.01.2014
comment
Я обнаружил, что VEC является производным от MAT, а mat определен в файле с именем mat_bones.hpp, в котором есть операторы () и []. arma_inline arma_warn_unused const eT & operator () (const uword i) const; ... Но я не вижу реализации.   -  person Darkgaze    schedule 19.01.2014
comment
Лично я бы просто изменил ваш класс, чтобы вместо этого использовать композицию. Это лишь внесет незначительные дополнительные хлопоты во время кодирования, но будет иметь полный доступ ко всем функциям публичного интерфейса Armadillo vec.   -  person Steven Hansen    schedule 19.01.2014
comment
@StevenHansen Хорошо. Звучит тоже нормально. Я должен вернуть тип vec позже. Я мог бы выполнить приведение в текущем случае или создать функцию, возвращающую включенный vec внутри ...   -  person Darkgaze    schedule 19.01.2014
comment
@ Гасим Да. Это ТАКАЯ библиотека. Думаю, он довольно известен.   -  person Darkgaze    schedule 19.01.2014
comment
Реализация класса Mat находится в Mat_meat.hpp . Класс vec на самом деле является typedef для класса Col ​​ используя double в качестве элементов (например, vec = Col ​​‹double›). Обратите внимание, что Armadillo уже определяет класс vec3 (typedef для Col ​​‹double› :: fixed ‹3›), так что вы можете захотеть назвать свой класс как-нибудь иначе.   -  person mtall    schedule 20.01.2014


Ответы (1)


at(0) = x; должен работать, если vec является производным от std :: vector, потому что функция at может возвращать непостоянную ссылку.

person Gasim    schedule 18.01.2014
comment
Ага! Это сработало. Интересно, что мне делать, например, если бы у меня не было этой функции. Лучше расширить, чем включить элемент класса? Думаю, это требует больше памяти. - person Darkgaze; 19.01.2014
comment
Включить (или составить) - отличный вариант, особенно если вы не вводите другие данные. - person Steven Hansen; 19.01.2014
comment
Еще одна мысль - как правило, неразумно полагаться на конкретную реализацию, предоставленную третьей стороной. Они могут решить, что хотят полностью изменить внутреннее устройство в своей следующей версии. - person Steven Hansen; 19.01.2014
comment
Итак ... использование at () тоже должно быть неправильным, верно? Я полагаюсь на их реализацию, потому что вынужден ею пользоваться. Эти простые векторы можно было сделать снаружи, но мне сказали сделать это. Что мне тогда делать? Позже мне придется вернуться к типам vec. Но преобразование vec3 в vec должно работать нормально, верно? - person Darkgaze; 19.01.2014
comment
Что ж, at () - это часть определенного интерфейса. Вы должны на это рассчитывать. Что не может быть определено, так это то, какие базовые классы использует библиотека (или любая внутренняя реализация в этом отношении). Итак, хотя на данный момент VEC может быть дочерним по отношению к MAT, который, в свою очередь, может быть дочерним по отношению к std :: vector, кто знает, будет ли это так в будущих версиях , если он не был указан как часть API. - person Steven Hansen; 19.01.2014
comment
Я сомневаюсь, что реализация класса Armadillo vec изменит своего родителя. Он явно задокументирован как производный от класса mat. Класс mat представляет матрицу, а класс vec - ограниченную матрицу. Это имеет смысл математически, поскольку вектор определяется как матрица с одной строкой или столбцом. - person mtall; 20.01.2014