2012-02-01 147 views
0

我正在試圖找到一個指南,甚至發現this,但它沒有提供答案。 我的問題是如何在構造函數中初始化一個C數組?下面我列舉一個我認爲正在做的事情的假設例子,但是我不知道它是好的還是錯誤的,完美的,或者只是出現了問題,並且有辦法讓它變得更好。C++:在類的構造函數中初始化字符數組和整數

class A{ 
private: 
    char* a; 
    int b; 
public: 
    A(char*, int); 
} 

A::A(char* _a, int _b){ 
    strcpy(a, _a); 
    b = _b 
} 

int main(){ 
    A tempA; 
    char arr[50]; 
    int c = 40; 

    strcpy(arr,"derp") 
    tempA = new A(arr,c) 

    return 0; 
} 

我目前還沒有接近我的C++專家,所以我希望能夠收到儘可能多的反饋。如果這是一個重複的問題,也很抱歉,但我真的沒有發現任何東西。

+1

你的例子中的數組在哪裏?指針不是數組,反之亦然。 – 2012-02-01 19:28:26

+0

你的例子中沒有數組,只有指針。 – 2012-02-01 19:29:05

+2

*只是說不。*使用'std :: string'。 – 2012-02-01 19:29:53

回答

4

如果要存儲一個字符串,可以存儲std::string

class A{ 
private: 
    std::string a; 
    int b; 
public: 
    A(std::string const&, int); 
} 

A::A(std::string const& _a, int _b) : a(_a), b(_b) {} 

如果你的老師堅持認爲,你把指針字符的字符串,那麼你有你的手一件複雜的事情,因爲你必須自己處理管理字符指向的內存,以免最後導致leaking memory。換句話說,你需要實現類似於std::string的東西。

因此,假設你真的需要做到這一點...

  • 每當你使用new你需要一個匹配delete以釋放new分配的內存;
  • 你可能想要new被類的構造函數調用;
  • 如果使用適當的析構函數自動存儲持續時間類的對象,自動爲您完成delete;
  • 該類可以不可複製(例如,通過製作私人拷貝構造函數和複製賦值操作符),或者如果您編寫proper copy constructorcopy assignment operator;
  • 您可以使用std::copy算法輕鬆製作副本,或者如果由於任意原因而受到限制,則可以使用舊的memcpystrcpy函數。

這並不是很簡單,但如果你這樣做,你將有一個非常方便的類,自動管理你的內存,讓你自由地專注於其他問題。

+0

對不起,我不能使用字符串,而我只是添加了缺少的代碼部分。對於這種困惑感到抱歉。 – 2012-02-01 19:33:32

+0

@SofiaAlegre:請說出你真正需要做的事情,並提出你的需求的最小,代表性和*完整的例子。這個不完整的「哦,但我不能做ABC我無緣無故分享」不會給你一個很好的答案。僅僅因爲*你認爲*你在正確的軌道上並沒有使這是最好的方法。 – 2012-02-01 19:35:28

+0

基本上我需要通過一個用戶數據庫創建多個用戶帳戶對象,這個用戶數據庫在從[actual]用戶(我)收集所有數據後在main方法中調用。我在這個特定的「問題」中的目的是學習如何將值從主方法中的一個char數組傳遞到另一個特定的新創建的類(a.k.a.用戶帳戶對象)中。這是否回答你的問題? – 2012-02-01 19:44:06

0

strcpy(a, _a)不會做你想做的事情:它假設a已經指向一些足夠大的內存以包含_a中的任何內容,事實並非如此。

這是最小的變更現有代碼:

A::A(char *_a, int _b) 
{ 
    a = strdup(_a); // makes a copy 
    b = _b; 
} 

更地道:使用初始化列表,有爲我們不會修改傳入的陣列(注意const):

A::A(char const *_a, int _b) 
    : a(strdup(_a)), b(_b) 
{ 
    // all the work was done above 
} 

而在一般情況下,這將是更好的C++風格來使用std::string,讓它操心你的記憶:

class A 
{ 
    std::string a; 
    int b; 
public: 
    A(char const *_a, int _b) : a(_a), b(_b) {} 

    // we can provide two versions, so you can pass in a std::string as well 
    A(std::string const &_a, int _b) : a(_a), b(_b) {} 
}; 

既然你無法使用std::string這個任務,你不會得到免費的內存管理,所以你需要編寫一個析構函數:

A::~A() 
{ 
    free(a); 
} 

否則你複製char *陣列當A的實例死亡時將被泄漏。順便說一句,你問題中的代碼無論如何都會泄漏整個A對象。

+0

謝謝,我也喜歡字符串,但我的教授現在只限制C字符串。 – 2012-02-01 19:37:24

+0

你不應該提到'strdup'而不提及'free'。 – 2012-02-01 19:37:45

+0

好吧,'strdup'是C風格的做法。哦,這讓我想起了 - 我忘了添加一個析構函數... @ R.MartinhoFernandes - snap! – Useless 2012-02-01 19:38:48

1

如果您需要使用c字符串(字符數組),您可以使用while循環。請記住,C++中的引號字符串(例如:「test」)是c字符串,但不是字符串。

class A 
{ 
private: 
    char* a; 
    int b; 
public: 
    char * get() {return a;} 
    A(char*, int); 
    A(); 
}; 

A::A(char* _a, int _b) 
{ 
    int i=0, lenth=0; 
    while(_a[i++]) 
     lenth++; 
    a= new char[lenth+1]; 
    i=0; 
    while(_a[i]) 
    { 
     a[i]=_a[i]; 
     i++; 
    } 
    a[i]=_a[i]; 

    b = _b; 
} 

int main() 
{ 
    A *tempA; 
    char arr[50]; 
    int c = 40; 

    strcpy(arr,"test string"); 
    tempA = new A(arr,c); 
    cout << tempA->get(); 

    return 0; 
} 
1

我認爲這是一個練習,你正試圖創建自己的字符串類。實際上,我認爲這是一個很好的練習。這實際上非常非常艱難。

在任何情況下,一旦您需要了解C++,就是「所有權」。在這種情況下,您的類A將擁有它分配的內存,並將負責稍後刪除它。

您需要爲new[]分配內存。然後你必須在delete[]之後刪除它。後者將在

class A 
{ 
    private:  
     char* a;  
     int b; 

    public:  
     A(const char*, int); 
     ~A(); 

}; 

A::A(const char * a_, int b_) 
: a(new char[b_+1], b(b_) 
{ 
    strncpy(a, a_, b); // could also use memcpy which would allow embedded nulls, 
     // in which case you must also add the null terminator yourself. 
} 

A::~A() 
{ 
    delete[] a; 
} 

我假定創建類通過在字符串作爲第二個參數的長度,用戶因此類必須聰明地分配額外的角色A的析構函數來完成爲空終止符

您的課程尚未完成。您需要處理: - 用戶如何閱讀字符串。 - 複製你的班級 - 分配你的班級。

請注意,您將得到一個自動生成的副本並分配它將複製並分配您班級的每個成員。問題是你將有2個實例持有相同的指針,他們都會嘗試刪除它。另外,被分配給的類已經有了一個它需要刪除的指針,並且這個指針最終會在空間中丟失(內存泄漏)。

我不會爲你回答這個問題,因爲你的練習是研究如何處理這種情況。