2010-09-15 25 views
19

Özel bir alanda gizli çok boyutlu bir diziyi nasıl döndürebilirim?C++ İşlevden çok boyutlu diziyi döndürme

class Myclass { 
private: 
int myarray[5][5]; 
public: 
int **get_array(); 
}; 

........ 

int **Myclass::get_array() { 
return myarray; 
} 

dönüş Test.cpp int** için int (*)[5][5] dönüştüremiyor/Polky/src hattı 73 C/C++ Sorun

+4

Kılavuz nedir? Myarray değil mi? – woodstok

+3

Özel bir üyeye yapılan doğrudan başvurunun yapılması her zaman iyi bir fikir olmayabilir. Bu şekilde kapsüllemeyi etkin bir şekilde kırıp, herhangi birinin özel üyenize erişmesine ve değiştirmesine izin verirsiniz. Bu tasarımınızda kabul edilebilir veya olmayabilir. –

+0

@MIkhail: justin bu soruyu gönderdiği andan beri çevrimiçi olmadığından, onu düzeltmek için özgürlüğümü aldım. – sbi

cevap

-1

sizin int en [] [] 'in int veya int kullanmayı denemek değiştirin [,] yerine ?

+1

'int [,]' C++ –

+3

... ve "int [] []' geçerli değil. Bu durumda, diziler ve işaretçiler arasındaki farkı anlamak önemlidir. – visitor

+2

@David: Aslında, 'new int [5, 5]' geçerli C++, sadece birinin düşünebileceği bir şey yapmıyor - bu, yeni int [5] 'in virgül operatörüne teşekkürler :) – fredoverflow

-1
int **Myclass::get_array() { 
return (int**)myarray; 
} 
+1

Hayır. Bunu kullanırsanız, dizinin öğelerini işaretçi olarak yeniden yorumlayacaksınız. –

+0

@Mike Seymour, ve her satırın int * olduğunu düşünürseniz bu doğrudur (int * olan tamsayıların her vektörü gibi). – rkellerm

4

dizi üyesi sizin diziye gösterici döndürmek için gerekli tip değil int **int (*)[5] geçerli:

class Myclass { 
private: 
    int myarray[5][5]; 
public: 
    int (*get_array())[5]; 
}; 

int (*Myclass::get_array())[5] { 
    return myarray; 
} 
1

Ben otomatik tip kesinti kullanarak C++ 0x ile bu fonksiyon çalışması için yönetilen . Ancak, o olmadan çalışamam. Yerli C dizileri C++ 'da çok iyi desteklenmez - onların sözdizimi aşırı derecede sakindir. Bir sarmalayıcı sınıfı kullanmalısınız.

template<typename T, int firstdim, int seconddim> class TwoDimensionalArray { 
    T data[firstdim][seconddim]; 
public: 
    T*& operator[](int index) { 
     return data[index]; 
    } 
    const T*& operator[](int index) const { 
     return data[index]; 
    } 
}; 
class Myclass { 
public: 
    typedef TwoDimensionalArray<int, 5, 5> arraytype; 
private: 
    arraytype myarray; 
public: 
    arraytype& get_array() { 
     return myarray; 
    } 
}; 

int main(int argc, char **argv) { 
    Myclass m; 
    Myclass::arraytype& var = m.get_array(); 
    int& someint = var[0][0]; 
} 

Bu kod düzgün bir şekilde derlenmiştir. Tüm shebang'ı destekleyen Boost (boost :: array) içinde önceden yazılmış sarmalayıcı sınıfını alabilirsiniz.

+0

GCC ile derleme yapmıyor: İlk geri dönüş verileri [index], bir değerden const olmayan bir başvuru yapar. – Cubbi

+0

Ve bu durumda, bir işaretçiye bir referans değil, bir çıplak işaretçi döndürülmelidir. Aksi halde, en azından okunabilirlikte çok fazla kazancımız var. Bir küçük nokta: Neden gerçek şablon türleri için 'int' kullanma? Olumsuz olabilecek bir şey, bence imzasız bir tamsayı türüyle daha iyi ifade edilir. –

+0

data [index] bir değer değil, bir değerdir, * gibi bir değer bir değerdir. Referansın gerçekten gerekli olduğunu düşünmüyorum, sanırım kodun önceki bir sürümünden, muhtemelen onu kaldırabilirsiniz. – Puppy

22

İki boyutlu bir dizi, işaretçiyi ints işaretçisine düşürmez. Ints dizilerine işaret eden bir göstericiye dönüşür - yani yalnızca ilk boyut bir göstericiye dönüşür. İşaretçi, bir işaretçinin boyutuna göre artırıldığında, ancak 5 tamsayı dizisine ilerleyen int işaretçilerine işaret etmez. Her bir alt dizini ayrı ayrı tahsis edildiğinde

class Myclass { 
private: 
    int myarray[5][5]; 
public: 
    typedef int (*pointer_to_arrays)[5]; //typedefs can make things more readable with such awkward types 

    pointer_to_arrays get_array() {return myarray;} 
}; 

int main() 
{ 
    Myclass o; 
    int (*a)[5] = o.get_array(); 
    //or 
    Myclass::pointer_to_arrays b = o.get_array(); 
} 

işaretçi için bir işaretçi (int**), beş işaretçiler bir dizi var Burada

int* p[5]; 
for (int i = 0; i != 5; ++i) { 
    p[i] = new int[5]; 
} 

(, başlangıçta işaretçiler bir dizi bilgisi yani) kullanılır her biri ayrı bir bellek bloğunda ilk maddeye işaret eder, toplam 6 ayrı bellek bloğu. iki boyutlu bir dizide

bellek bitişik tek bir blok almak:

int arr[5][5]; //a single block of 5 * 5 * sizeof(int) bytes 

Bu şeylerin bellek düzeni tamamen farklıdır ve bu nedenle bunları döndü ve geçilemeyen görmelisiniz aynı şekilde.

+0

+1 teşekkürler, büyük yanıt –

2

Özel bir alanda gizli çok boyutlu bir diziyi nasıl döndürebilirim?

Gizlenmesi gerekiyorsa, neden ilk etapta geri dönüyorsunuz?

Her neyse, dizileri işlevlerden döndüremezsiniz, ancak bir işaretçiyi ilk öğeye dönüştürebilirsiniz. 5x5'lik bir dizi dizinin ilk elemanı nedir? Tabii 5 ints dizisi,:

int (*get_grid())[5] 
{ 
    return grid; 
} 

Alternatif olarak, referans olarak bütün diziyi geri dönebilirler:

int (&get_grid())[5][5] 
{ 
    return grid; 
} 

...C declarator sözdizimi cehennemine hoş geldiniz ;-)

Bunun yerine std::vector<std::vector<int> > veya boost::multi_array<int, 2> önerebilir miyim?

16

Dahili dizinize erişim sağlamak için geri dönebileceğiniz iki olası tür vardır. Eski C stili, int[5] türünde olan birinci elemana bir işaretçi kolayca dönüşebileceğinden, int *[5] geri dönecektir.

int (&foo())[5][5] { 
    static int array[5][5] = {}; 
    return array; 
} 
: typedef olmadan

typedef int (&array5x5)[5][5]; 
array5x5 foo() { 
    static int array[5][5] = {}; 
    return array; 
} 

Veya biraz daha hantal:

int (*foo())[5] { 
    static int array[5][5] = {}; 
    return array; 
} 

Şimdi, aynı zamanda iç diziye uygun bir başvuru dönebilirsiniz, en basit sözdizimi bir typedef yoluyla olacağını

C++ sürümünün avantajı, gerçek türün korunmuş olmasıdır ve bu, dizinin gerçek boyutunun arayan tarafında bilindiği anlamına gelir.

+0

+1 C++ sürümü için (uygun typedef ile) –

+1

Bu typedefleri nasıl kullandığınıza dikkat edin, bazen: 'delete [] new array5x5()' (yeni gibi görünüyor, ama gerçekten yeni []). –

İlgili konular