2010-06-24 155 views
1

我是一個間歇性程序員,最近似乎忘記了很多基礎知識。函數返回指向常量2-d數組的指針(C++)

我創建了一個類SimPars來保存幾個二維數組;下面顯示的是demPMFs。我要將一個指向SimPars實例的指針傳遞給其他類,並且我希望這些類能夠使用SimPars訪問器函數讀取數組。速度和記憶很重要。

我知道生活對於向量來說往往更簡單,但在這種情況下,我真的很想堅持陣列。

如何爲數組寫入存取器函數?如果我對第n個數組索引感興趣,我將如何使用返回的指針訪問它? (我應該爲數組的一個特定的索引編寫一個單獨的訪問器函數嗎?)下面的內容肯定是錯誤的。

// SimPars.h 
#ifndef SIMPARS_H 
#define SIMPARS_H 
#include "Parameters.h" // includes array size information 

class SimPars { 
public: 
    SimPars(void); 
    ~SimPars(void); 

    const double [][ INIT_NUM_AGE_CATS ] get_demPMFs() const; 

private: 
    double demPMFs[ NUM_SOCIODEM_FILES ][ INIT_NUM_AGE_CATS ]; 

}; 
#endif 


// SimPars.cpp 
SimPars::SimPars() { 
demPMFs[ NUM_SOCIODEM_FILES ][ INIT_NUM_AGE_CATS ]; 
// ...code snipped--demPMFs gets initialized... 
} 

//...destructor snipped 
const double [][ INIT_NUM_AGE_CATS ] SimPars::get_demPMFs(void) const { 
    return demPMFs; 
} 

我會非常感謝某些解釋與建議的解決方案。

+0

我很確定成員聲明'double demPMFs [] [INIT_NUM_AGE_CATS];'是非法的。這實際上是編譯? – fredoverflow 2010-06-24 18:46:15

+0

感謝您的支持。修正了錯字。我有原始代碼的大小。 – Sarah 2010-06-24 18:49:05

+0

您能否詳細說明您實際嘗試實現的目標?考慮一個2維數組作爲指針:'demPMFs **'的數組,那麼你不需要像在const const [] [INIT_NUM_AGE_CATS] get_demPMFs()const;'中那樣在返回類型中指定任何大小......「 – nus 2010-06-24 18:51:04

回答

3

基本上,你有三個選擇:通過引用返回整個數組,通過指針返回第一行,或者通過指針返回整個數組。下面是執行:

typedef double array_row[INIT_NUM_AGE_CATS]; 

typedef array_row array_t[NUM_SOCIODEM_FILES]; 

array_t demPMFs; 

const array_t& return_array_by_reference() const 
{ 
    return demPMFs; 
} 

const array_row* return_first_row_by_pointer() const 
{ 
    return demPMFs; 
} 

const array_t* return_array_by_pointer() const 
{ 
    return &demPMFs; 
} 

這裏是用例:

SimPars foo; 

double a = foo.return_array_by_reference()[0][0]; 
double b = foo.return_first_row_by_pointer()[0][0]; 
double c = (*foo.return_array_by_pointer())[0][0]; 

我怎麼會只返回數組的第n行?

同樣,你有三種選擇:

const array_row& return_nth_row_by_reference(size_t row) const 
{ 
    return demPMFs[row]; 
} 

const double* return_first_element_of_nth_row_by_pointer(size_t row) const 
{ 
    return demPMFs[row]; 
} 

const array_row* return_nth_row_by_pointer(size_t row) const 
{ 
    return demPMFs + row; 
} 
+0

謝謝。我將如何返回陣列的第n行? – Sarah 2010-06-24 19:02:26

+1

@Sarah:我更新了我的帖子。在這兩種情況下,我都會更喜歡第一種解決方案,通過引用返回您感興趣的完整內容。 – fredoverflow 2010-06-24 19:06:30

1
const double (* get_demPMFs() const)[INIT_NUM_AGE_CATS]; 

或者,使用typedef(但那看起來並不清潔......)。

class SimPars { 
    typedef const double (*ConstDemPMFType)[INIT_NUM_AGE_CATS]; 

    double demPMFs[NUM_SOCIODEM_FILES][INIT_NUM_AGE_CATS]; 
public: 
    ConstDemPMFType get_demPMFs() const; 
}; 

請注意,您不能返回數組(g++拒絕編譯)。但是一個數組的數組可以衰減到一個指向數組的指針,所以後者被返回。

+0

'(* get_demPMFs()const)' - >啊,這就是括號和const必須去的地方,我和C語言的聲明語法打了5分鐘並放棄了,退到了老式的typedef :) – fredoverflow 2010-06-24 19:07:23

+1

@Fred this是身份認同的地方。 'identity :: type * get_demPMFs()const;' – 2010-06-26 23:31:31

0

按理來說有一個數據成員這個問題。應該允許用戶修改或不修改。如果你想讓另一個班級完全訪問成員,你不一定需要getter/setter,特別是如果你是唯一的用戶。你可以公開成員。

如果你的班級最好控制用戶訪問成員的方式,那麼你可以使用getter來強制只讀訪問。最簡單的方式做到這一點,如果你不想讓所有困惑的2維數組是隻具有一個內聯函數獲取的元素爲用戶等級:

const double& getElem(int x, int y) const { return demPMF[x][y] } 

它情理之中的事界限在這裏檢查,但考慮到你堅持使用數組,並且如果你的配置文件證明你買不起它,這個函數只允許訪問你的數組。

如果您想進一步闡述,請發表評論...

+0

如何通過const引用傳遞整個數組的安全性較低? – fredoverflow 2010-06-24 19:25:31

+0

O,絕對不是那麼安全,但它更混亂,至少對我來說這簡單得多。我仍然試圖弄清楚你的語法和肯尼的答案。 – nus 2010-06-24 19:32:17