2017-01-17 5 views
0

Я не могу создать 2D-массив в MFC в соответствии с кодом «CArray> & results». Код:Как создать "CArray <CArray <CString>> & results" в MFC?

CArray<CArray<CString>> res; 

    CArray<CString>strArray1; 

    strArray1.Add(L"Ali"); 
    strArray1.Add(L"Ahmed"); 
    strArray1.Add(L"Mark"); 

    CArray<CString>strArray2; 

    strArray2.Add(L"1"); 
    strArray2.Add(L"2"); 
    strArray2.Add(L"3"); 

res.Add(strArray1); 
res.Add(strArray2); 

Ошибка после выполнения: ошибка C2248: «CObject :: оператор =»: не может получить доступ к закрытому члену, объявленный в классе «CObject»

Это должно быть сделано без перекрывая копии и равен метод в CArray, вместо этого существует какой-либо способ, когда мне не нужны те косвенно, как какой-то метод CArray, который можно использовать.

+0

C2248 - ошибка компилятора, а не ошибка выполнения. Какая строка в приведенном выше фрагменте указывает на ошибку компилятора? – andlabs

+0

Являются ли классы контейнеров MFC по-прежнему актуальными в этот день и возраст C++? Вы можете просто использовать 'std :: vector >'. – PaulMcKenzie

+0

@andlabs - ошибка компилятора связана с строкой «res.Add (strArray1)»; – offeron

ответ

4

Сигнатура CArray::Add() является

INT_PTR Add(ARG_TYPE newElement); 

Вы заметите, что newElement аргумент передается по значению. Это означает, что тип элемента должен быть доступен для копирования, а CObject s - нет. Это не особенно хорошо документировано; в части документации CMap указано, что тип значения карты должен быть выполнен с возможностью копирования, поэтому мы можем предположить, что остальная часть API была разработана аналогичным образом.

This question объясняет, почему CObject s не могут быть скопированы.

Итак, что вы можете сделать? У вас есть несколько вариантов.

  • Переключиться на использование CArray<CArray<CString> *> - хранить внутренние массивы измерений в качестве указателей вместо значений; это также экономит память
  • коммутатор к использованию CTypedPtrArray<CObjArray, CArray<CString> *>, что позволяет использовать CObArray вместо этого, и по-прежнему типобезопасного
  • переключиться на использование стандартных C++ контейнеров, а именно std::vector<std::vector<CString> >, как было предложено выше @PaulMcKenzie. CString не является CObject, поэтому вы можете использовать его напрямую. В качестве альтернативы, если вы используете только CString в качестве обертки вокруг строк C, вы также можете переключиться на std::string или std::wstring, но только делайте это, если знаете, что делаете.
  • Конечно, если вам нужен внутренний размер CArray, вы также можете сделать std::vector<CArray<CString> *>. Как обычно, шаблон требует, чтобы вы использовали указатели - вы не можете просто сказать std::vector<CArray<CString> > по той же причине, что и выше (std::vector требует возможности копирования).
  • Используйте одномерный массив (CArray<CString> или std::vector<CString> или что-то еще) размера m * n (где m - размер внутреннего измерения). В этом случае arr[i][j] в вашем фрагменте кода совпадает с arr[i * m + j]. Фактически, это то, к чему сводятся многомерные массивы, поскольку примеры учебников по матричному умножению в C покажут. (Спасибо @Inpectable, чтобы напомнить мне об этом.)
+1

Другим вариантом было бы отобразить двумерный массив на одномерный. – IInspectable

+0

О, я совсем забыл об этом варианте! Благодарю. – andlabs

+1

Все еще важно отметить, что отображение двумерного массива на одномерное работает только для прямоугольных матриц (т. Е. Массивов, где все строки имеют одинаковое количество столбцов). Если у вас есть зубчатый массив, вы должны продолжать использовать массив массивов. – IInspectable