問題代碼
CvPoint point1;
CPoint m_head[0]; // 語法錯誤:數組聲明不能帶下標
// 嘗試
point1.x = m_head[0].x;
point1.y = m_head[0].y;
// 或自定義函數 Change_Point(point1, m_head[0]);
// 運行時報「聲明錯誤」
錯誤分析
CPoint m_head[0] 非法聲明: 數組定義時不能指定下標。應為 CPoint m_head[10]; 或 std::vector<CPoint> m_head;。
- 未分配內存/未初始化: 若
m_head 是指針 (CPoint* m_head),需 new CPoint[n] 或指向有效內存。**訪問 m_head[0] 野指針導致崩潰/報錯**。
- 結構體定義差異:
// OpenCV 2.x C API
typedef struct CvPoint { int x; int y; } CvPoint;
// MFC/ATL CPoint
class CPoint : public tagPOINT {
public: int x; int y; // 繼承自 tagPOINT { LONG x; LONG y; }
};
內存布局**完全兼容** (兩個 int/long 連續),**直接逐字段賦值安全**。
正確轉換代碼
// 假設 m_head 是有效的 CPoint 數組/向量
CvPoint cvPt;
cvPt.x = m_head[0].x; // 隱式轉換 long -> int (注意範圍)
cvPt.y = m_head[0].y;
// 或使用構造函數 (CPoint 有構造函數)
CPoint mfcPt(cvPt.x, cvPt.y); // CvPoint -> CPoint
// 批量轉換
std::vector<CvPoint> cvPts;
std::vector<CPoint> mfcPts(cvPts.size());
std::transform(cvPts.begin(), cvPts.end(), mfcPts.begin(),
[](const CvPoint& p) { return CPoint(p.x, p.y); });
避坑指南
- 指針 vs 對象:
CPoint* p = new CPoint[10]; 訪問 p[0] 有效;CPoint p[10]; 訪問 p[0] 有效;CPoint p[0]; **編譯錯誤**。
- 類型長度: 64 位系統
LONG (CPoint) 可能 4 字節 (Windows) 或 8 字節 (Linux),int (CvPoint) 通常 4 字節。**數值溢出風險極低** (坐標很少超過 2^31)。
- OpenCV 3/4 C++ API: 推薦直接用
cv::Point (模板類),與 CPoint 互轉同理。