문제

OpenCV 라이브러리와 함께 C ++를 사용하고 있습니다.이 질문은이 질문과 관련이 없지만 라이브러리 이미지 처리입니다. 현재 나는 디자인 결정을 내 렸습니다.

C 라이브러리 인 OpenCV에는 데이터 구조 (예 : CVMAT)가 스트러크로 선언된다. 그것들을 만들려면 cvcreatemat와 같은 함수를 사용하고 해제하려면 cvreleasemat와 같은 함수를 사용합니다. C ++ 프로그래머이기 때문에 나는 특별한 cv_scoped CVReleAsemat가 자동으로 범위를 벗어 났을 때 자동으로 호출하는 클래스 boost::scoped_ptr).

내가 지금 깨닫는 것은 내가 사용할 수 있기를 바랍니다. auto_ptr 그리고 shared_ptr 경우에도. 나는 단지 내 자신의 글쓰기 코드를 느낍니다 cv_auto_ptr 그리고 cv_shared_ptr 수업은 시간 낭비는 말할 것도없이 나쁜 생각이 될 것입니다. 그래서 저는 솔루션을 찾고 있었고 세 가지 가능성을 생각해 냈습니다.

첫 번째, 나는 이미 만든 CV_SCOPED 클래스를 사용할 수 있습니다. 나는 그것을 이름으로 바꿀 것입니다 cv_ptr 그런 다음 STAL과 같은 스마트 포인터를 사용하십시오. 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 함수에는 매개 변수가 없습니다. 따라서 암시 적 변환이 호출되지 않을 것입니다. 나는 이중 단절을 할 필요가없는 곳에서 이것을하는 방법을 정말로 원합니다.

, 나는 어떻게 든 재정의 할 수 있습니다 operator 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
}

내 상황에서 무엇을 하시겠습니까? 이것을 알아 내도록 도와주세요.

도움이 되었습니까?

해결책

Auto_ptr은 C ++ 클래스에서 RAII 용으로 설계되었습니다. 구조물/파괴자는 여기에 사용하지 말아야 할 것 (그러나 할 수있는)으로 여기에 사용하는 것입니다.

어쨌든 매번 동적으로 할당하지 않고 C ++ 객체를 일반 스택 변수 인 것처럼 사용하고 싶습니까?

문제에 대한 표준 솔루션은 생성자/파괴자가있는 래퍼를 만드는 것입니다.
그러나 C 함수에 의해 사용할 수 있도록 내부 캐스트 연산자를 추가하여 C 함수로 전달 될 때 자동으로 C 객체로 다시 변환합니다.

래퍼 클래스를 작성하십시오.

class Mat
{
    CvMat* impl;
    public:
        Mat(/* Constructor  Arguments */)
        {
            impl = cvCreateMat(/* BLAH */);
        }
        ~Mat()
        {
            cvReleaseMat(impl);
        }
        operator CvMat*()
        {   // Cast opertator. Convert your C++ wrapper object into C object
            // when you use it with all those C functions that come with the
            // library.

            return impl;
        }
};

void Plop(CvMat* x)
{   // Some C function dealing with CvMat
}

int main()
{                            // Don't need to dynamically allocate
    Mat                  m;  // Just create on the stack.
    Plop(m);                 // Call Plop directly

    std::auto_ptr<Mat>   mP(new Mat);
    Plop(*mP);
}

다른 팁

당신이 고려할 수있는 한 가지 방법은 std::tr1::shared_ptr 사용자 정의 델리터를 제공 할 수있는 기능이 있습니다. 나는 OpenCV에 익숙하지 않아서 당신이 쓴 내용에서 유추하고 있습니다.

struct CvMatDeleter
{
    void operator( CvMat* p ) { cvReleaseMat( p ) ; }
};

void test()
{
    std::tr1::shared_ptr< CvMat > pMat( cvCreateMat(320, 240, CV_32FC3), CvMatDeleter() );
    // . . .
}

Deleter는 공유 포인터에 매장이므로 공유 원시 포인터를 최종적으로 삭제해야 할 때만 사용할 수 있습니다. cvReleaseMat 필요에 따라 호출됩니다. 주목하십시오 auto_ptr 그리고 scoped_ptr 훨씬 가벼운 클래스이므로 사용자 정의 삭제 기능이 없지만 작은 오버 헤드에 대비할 준비가된다면 shared_ptr 대신에 사용할 수 있습니다.

당신이 관심있는 모든 것이 예외 안전이라면, 매트릭스를 사용할 때마다 이것을하십시오.

void f() {
    try {
        CvMat* mat = cvCreateMat(320, 240, CV_32FC3));
        // ...
    } catch(...) {
        cvReleaseMat(mat);
        throw;
    }
    cvReleaseMat(mat);
}

반면에, 당신은 제정신 해결책, 여분의 마일을 가서 풀 래퍼를 작성하십시오.

namespace cv {

class Mat {
public:
    enum Type { /* ... */ };
    Mat(int w, int h, Type type) {
        impl = cvCreateMat(w, h, intFromType(type));
    }

    ~Mat() {
        cvReleaseMat(impl);
    }

    void pow() { // wrap all operations
        cvPow(impl);
    }

private:
    CvMat* impl;
};

}

중간 길을 가면서 일반적인 스마트 포인터와 "CV_PTRS"의 Hodge Podge를 사용하는 것은 두통의 레시피와 불필요한 합병증처럼 들립니다.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top