MFC CArray 作為函數參數傳遞與回傳值時,若不當處理易觸發「缺少拷貝建構函數」編譯錯誤。本文系統解析三種傳遞模式、結構體嵌套應用與實戰範例。
| 模式 | 宣告範例 | 特點 | 適用場景 |
|---|---|---|---|
| 值傳遞 | void Func(CArray<int,int> arr) | 觸發拷貝建構,**需元素型別支援拷貝**,效能差 | 極少用,除非刻意需副本 |
| 引用傳遞 (推薦) | void Func(CArray<int,int>& arr) | 無拷貝、可修改原陣列、效能最佳 | 輸出參數、雙向資料交換 |
| 指標傳遞 | void Func(CArray<int,int>* pArr) | 無拷貝、可為 NULL、語義明確輸出 | 輸出參數、選擇性修改 |
| const 引用 | void Func(const CArray<int,int>& arr) | 無拷貝、唯讀、可接臨時物件 | 輸入參數、不修改內容 |
CArray // Type: 回傳/儲存類型, ArgType: 輸入/傳遞類型
// 範例
CArray arr1; // Add/GetAt 使用 double (值傳遞)
CArray arr2; // Add/GetAt 使用 double& (引用傳遞,避免拷貝)
CArray arr3; // 結構體建議用引用避免拷貝
CArray arr4; // 指標陣列
struct DriverItem {
CString strDriverName;
CString strProductDesc;
CString strTBLFileName;
};
struct ControlItem {
CString strControlType;
CArray DriverArray; // 引用型別避免拷貝
};
// 自訂雙精度點結構 (含拷貝建構/指派,滿足 CArray 需求)
struct CPointD {
double x, y;
CPointD() : x(0), y(0) {}
CPointD(double dx, double dy) : x(dx), y(dy) {}
CPointD(const CPointD& p) : x(p.x), y(p.y) {}
CPointD& operator=(const CPointD& rhs) { x=rhs.x; y=rhs.y; return *this; }
};
typedef CArray CPointDArray; // 值型別
typedef CArray LPointArray; // 長整數點引用型別
class CMyView : public CView {
CPointDArray m_points; // 成員變數
// 轉換函數:const 引用輸入,引用輸出
void ConvToXYs(const CPointDArray& src, LPointArray& dest) {
if (src.GetSize() == 0) return;
dest.RemoveAll();
dest.SetSize(src.GetSize());
for (int i = 0; i < src.GetSize(); i++) {
const CPointD& p = src[i]; // 引用存取,無拷貝
dest[i].x = static_cast(p.x + 0.5);
dest[i].y = static_cast(p.y + 0.5);
}
}
void OnLButtonDown(UINT nFlags, CPoint point) {
CClientDC dc(this);
// 產生測試資料
for (int i = 0; i < 10; i++)
m_points.Add(CPointD(i * 3.5, i * 5.5));
LPointArray longPoints;
ConvToXYs(m_points, longPoints);
// 繪製折線 (GetData() 取得內部緩衝區指標)
dc.Polyline(longPoints.GetData(), m_points.GetSize());
CString str; str.Format(_T("點數: %d"), longPoints.GetSize());
AfxMessageBox(str);
}
~CMyView() { if (m_points.GetSize()) m_points.RemoveAll(); }
};
CArray 避免 Add/GetAt 拷貝std::vector 或輸出參數模式新專案優先考慮 std::vector:標準化、移動語義、分配器支援、算法整合。維護舊 MFC 專案時,掌握上述模式確保 CArray 安全高效使用。