2010-02-22 51 views
6

我有這個問題很長一段時間 - 我有固定大小的2D數組作爲類成員。將指針傳遞給二維數組C++

class myClass 
{ 
public: 
     void getpointeM(...??????...); 
     double * retpointM(); 

private: 

    double M[3][3]; 

}; 

int main() 
{ 
    myClass moo; 
    double *A[3][3]; 

    moo.getpointM(A); ??? 
    A = moo.retpointM(); ??? 

} 

我想將指針傳遞給M矩陣外部。這可能很簡單,但我找不到&*等的適當組合。

感謝您的幫助。

回答

9

double *A[3][3];double *的2維陣列。你想要double (*A)[3][3];

然後,請注意,A*A和都具有相同的地址,只是不同的類型。

製作的typedef可以簡化事情:

typedef double d3x3[3][3]; 

這是C++,你應該通過引用傳遞變量,不是指針:

void getpointeM(d3x3 &matrix); 

現在你不需要使用括號中類型名稱,並且編譯器確保您傳遞了正確大小的數組。

+0

你不應該使用引用「因爲這是C++」或「只是因爲你可以」。當他們比可用的替代品更清晰時使用它們。 – 2010-02-22 05:18:46

+0

@Roger:是的,在這裏,無論如何,這是適當的:v) – Potatoswatter

0

簡短的回答是,你可以得到一個double *到數組的開始:

public: 
    double * getMatrix() { return &M[0][0]; } 

類外,但是,你不能真正把平凡的double *到另一個二維數組直接在至少不是我見過的模式。

雖然(double A [3] [3]),您可以在main中創建一個二維數組,並將傳入一個getPoint方法,該方法可以將值複製到傳入的數組中。這會給你一個副本,這可能是你想要的(而不是原始的,可修改的數據)。缺點是你必須複製它,當然。

+0

不!不要放棄! – Potatoswatter

0

在你main()功能:

double *A[3][3]; 

創建的double*一個3×3陣列(或指針雙打)。換句話說,9個32位連續字的內存可以存儲9個內存指針。

除非該類將被銷燬,您仍然需要訪問此信息,否則沒有必要將此數組的副本複製到main()。相反,您可以簡單地返回一個指向此成員數組開頭的指針。

如果你只是想返回一個指向一個內部類成員,真正需要的只是在main()一個指針值:

double *A; 

但是,如果你通過這個指針的函數,你需要的功能來更新它的價值,你需要一個雙指針(這將使該函數返回真正指針的值返回給調用者:

double **A; 

而且裏面getpointM()您只需點A到內部成員(M):

getpointeM(double** A) 
{ 
    // Updated types to make the assignment compatible 
    // This code will make the return argument (A) point to the 
    // memory location (&) of the start of the 2-dimensional array 
    // (M[0][0]). 
    *A = &(M[0][0]); 
} 
+0

好吧,這似乎是我真的想做的事情:)但仍然有錯誤:無法將'double [3] [3]'轉換爲'double *'在作業中 – Moomin

+0

對不起我的錯誤 - 忘了在兩行中都添加** – Moomin

+2

這對我來說沒有任何意義。該成員被聲明爲'double M [3] [3]'。 Assigment'* A = M'根本不會編譯,因爲左邊是'double *',右邊是'double(*)[3]'。這些類型不兼容。 – AnT

0
class myClass 
{ 
public: 
     void getpointeM(double *A[3][3]) 
     { 
      //Initialize array here 
     } 

private: 

    double M[3][3]; 

}; 

int main() 
{ 
    myClass moo; 
    double *A[3][3]; 

    moo.getpointM(A); 
} 
3

你的意圖是不明確的。 getpointeM應該做什麼?返回一個指向內部矩陣的指針(通過參數),還是返回矩陣的一個副本?

要返回一個指針,你可以做到這一點

// Pointer-based version 
... 
void getpointeM(double (**p)[3][3]) { *p = &M; } 
... 
int main() { 
    double (*A)[3][3]; 
    moo.getpointM(&A); 
} 

// Reference-based version 
... 
void getpointeM(double (*&p)[3][3]) { p = &M; } 
... 
int main() { 
    double (*A)[3][3]; 
    moo.getpointM(A); 
} 

retpointM的聲明將如下所示

... 
double (*retpointM())[3][3] { return &M; } 
... 
int main() { 
    double (*A)[3][3]; 
    A = moo.retpointM(); 
} 

這是相當困難的,雖然閱讀。你可以,如果你使用typedef,名稱爲您的數組類型

typedef double M3x3[3][3]; 

在這種情況下,上面的例子會變成

// Pointer-based version 
... 
void getpointeM(M3x3 **p) { *p = &M; } 
... 
int main() { 
    M3x3 *A; 
    moo.getpointM(&A); 
} 

// Reference-based version 
... 
void getpointeM(M3x3 *&p) { p = &M; } 
... 
int main() { 
    double (*A)[3][3]; 
    moo.getpointM(A); 
} 

// retpointM 
... 
M3x3 *retpointM() { return &M; } 
... 
int main() { 
    M3x3 *A; 
    A = moo.retpointM(); 
} 
0

您可能需要採取的代碼看起來更加清晰你的主函數可以和二維數組一起工作,並將它作爲成員函數移動到myClass中。您不但不需要處理爲2D數組傳遞指針的困難,而且您的類外部的代碼不再需要知道類的實現細節,因爲它們現在將調用一個函數myClass並讓它完成這項工作。如果您後來決定允許A的可變維度並選擇用vectorvector s替換該陣列,則無需重寫任何調用代碼即可使其工作。

0

讓M公開而不是私人。既然你想允許通過指針訪問M,那麼M就不會被封裝了。

struct myClass { 
    myClass() { 
    std::fill_n(&M[0][0], sizeof M/sizeof M[0][0], 0.0); 
    } 
    double M[3][3]; 
}; 

int main() { 
    myClass moo; 
    double (*A)[3] = moo.M; 
    double (&R)[3][3] = moo.M; 

    for (int r = 0; r != 3; ++r) { 
    for (int c = 0; c != 3; ++c) { 
     cout << A[r][c] << R[r][c] << ' '; 
     // notice A[r][c] and R[r][c] are the exact same object 
     // I'm using both to show you can use A and R identically 
    } 
    } 

    return 0; 
} 

我想,在一般情況下,寧可- [R超過因爲所有被固定(可能指向一個double[10][3],如果這是一個要求)和參考通常的長度的導致更清晰的代碼。