Я использую C ++ с библиотекой OpenCV, которая является библиотекой обработки изображений, хотя это не относится к этому вопросу. В настоящее время у меня есть дизайнерское решение.
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
}
Что бы вы сделали в моей ситуации? Пожалуйста, помогите мне разобраться с этим.