Я использую C++ с библиотекой OpenCV, которая представляет собой библиотечную обработку изображений, хотя это не относится к этому вопросу. В настоящее время у меня есть дизайнерское решение.Умные указатели с библиотекой, написанной на языке C
OpenCV, являющийся библиотекой C, имеет свои структуры данных (такие как CvMat), объявленные как структуры. Чтобы создать их, вы используете такие функции, как cvCreateMat, и для их выпуска вы используете такие функции, как cvReleaseMat. Будучи программистом на C++, я создал специальный класс cv_scoped
, который автоматически вызывается cvReleaseMat, когда он выходит из сферы действия (например, boost::scoped_ptr
).
То, что я понимаю сейчас, это то, что я хотел бы использовать auto_ptr
и shared_ptr
в случаях. Я просто чувствую, что писать код для моих собственных классов cv_auto_ptr
и cv_shared_ptr
будет плохой идеей, не говоря уже о пустой трате времени. Поэтому я искал решения, и у меня появились три возможности.
Первый, я мог бы использовать класс cv_scoped, который я уже сделал. Я бы переименовал его в cv_ptr
, а затем использовал интеллектуальные указатели, например: std::auto_ptr<cv_ptr>
. Раздражающая вещь об этом, хотя это, я всегда должен разыменованию дважды:
std::auto_ptr<cv_ptr> matrix(cv_ptr(cvCreateMat(320, 240, CV_32FC3)));
cvPow(matrix.get()->get()); // one get for the auto_ptr, one for the cv_ptr
Я знаю, это выглядит, как я мог бы объявить неявное преобразование, но я не мог на самом деле - большинство функций OpenCV имеет параметра void * - поэтому не будет вызвано неявное преобразование. Мне бы очень хотелось сделать это, когда мне не пришлось делать двойное разыменование.
Второй, я мог бы как-то переопределить operator delete
. Я не хочу переопределять глобальный оператор delete, потому что я бы хотел, чтобы это применимо к CvMat (и нескольким другим) типам. Однако я не могу изменить библиотеку, поэтому я не могу добавить operator delete
в структуру CvMat. Поэтому я не знаю, как это будет работать.
Третьего, я мог бы просто переписать мой собственный auto_ptr
, scoped_ptr
и shared_ptr
. Они не большие классы, поэтому было бы не слишком сложно, но я просто чувствую, что это плохой дизайн. Если бы я это сделать, я бы, вероятно, сделать что-то вдоль этих линий:
class cv_auto_ptr {
public:
cv_auto_ptr();
~cv_auto_ptr();
// each method would just be a proxy for the smart pointer
CvMat* get() { return this->matrix_.get()->get(); }
// all the other operators/methods in auto_ptr would be the same, you get the idea
private:
auto_ptr<cv_ptr> matrix_; // cv_ptr deletes CvMat properly
}
Что бы вы сделали в моей ситуации? Пожалуйста, помогите мне разобраться в этом.
Я думал об этом около 15 минут, и я думаю, что вы можете быть на лучшее решение здесь. Различия в этом и других решениях являются тонкими, но очень важными. Я подумаю об этом немного дольше, прежде чем принимать этот ответ. –