2017-04-02 85 views
-1

我構建了一個名爲CMyString類,這裏是:字符* =新的字符與char * =新的char [N]

class CMyString { 
public: 
    CMyString(); 
    CMyString(char* pData); 
    CMyString(const CMyString& str); 
    ~CMyString(void); 

    char* getData(); 
    void setData(char* pData); 

    CMyString& operator=(const CMyString& str); 

private: 
    char* m_pData; 
}; 

    CMyString::CMyString() { 
    m_pData = new char; 
} 

CMyString::CMyString(char* pData) { 
// m_pData = new char; 
    m_pData = pData; 
} 

CMyString::CMyString(const CMyString& str) { 
    // 爲指針分配內存 
// m_pData = new char; 
    // 拷貝值 
    m_pData = str.m_pData; 
} 

CMyString::~CMyString(void) { 
// delete m_pData; 
} 

CMyString& CMyString::operator=(const CMyString& str) { 
    if (this == &str) 
     return *this; 

    delete m_pData; 
    m_pData = nullptr; 
    m_pData = new char[strlen(str.m_pData) + 1]; 
    strcpy(m_pData, str.m_pData); 

    return *this; 
} 

char* CMyString::getData() { 
    return m_pData; 
} 

void CMyString::setData(char *pData) { 
    m_pData = pData; 
} 

這裏是我的main.cpp:

#include <iostream> 
#include "CMyString.h" 

using std::cout; 
using std::endl; 

int main() { 
    char* pData = "What are you worrying about?"; 
    std::cout << pData << std::endl; 

    cout << strlen(pData) << endl; 
    char* test = new char[30]; 
    cout << sizeof(test) << endl; 
    char* test2 = new char; 
    test2 = "23"; 
    cout << test2 << endl; 

    strcpy(test, pData); 

    cout << endl << test << endl << endl; 

    CMyString str(pData); 
    std::cout << str.getData() << std::endl; 

    CMyString str2, str3; 
    str3 = str2 = str; 

    std::cout << str3.getData() << endl; 

    char* pData2 = "Data has been changed."; 
    str3.setData(pData2); 

    cout << str.getData() << endl; 
    cout << str2.getData() << endl; 
    cout << str3.getData() << endl; 

    return 0; 
} 

那麼我很困惑的

char* pData = new char; 
char* pData2 = new char[30]; 

我在類的實現嗎? 我怎麼能告訴兩個不同的指針? 我是否正確地編寫構造函數和解構造函數和運算符?如果不是,如何編寫它們?

+0

兩件事:你不想混合'新的char'和'新的char [n]'。它們需要稍微不同的刪除('delete'和'delete []'),並且幾乎不可能從指針中找出使用哪一個。接下來,'char * str =「一個字符串」;'在pre C++ 11代碼中是不好的形式,之後是非法的。 「一個字符串」是一個字符串文字,可以存儲在不可寫入的存儲器中。它應該是一個'const char *'來防止無法寫入的意外程序崩潰寫入int。 – user4581301

+0

您的副本構造函數導致源和副本都指向相同的字符串。一旦你完全實現了析構函數,這很糟糕,因爲它們都會試圖銷燬相同的字符串和其他不好的東西。您將需要分配一個新緩衝區來存放源字符串的副本,然後複製到該緩衝區中。 – user4581301

+0

有用的閱讀:http://stackoverflow.com/questions/3279543/what-is-the-copy-and-swap-idiom – user4581301

回答

0
char* pData = new char; -> Allocates one piece/slot of memory 
char* pData2 = new char[30]; -> Allocates 30 continuous pieces/slots of memory 

第一個使用delete pData,第二個delete [] pData

而且除了這個,你正在使用char *pData = "STRING",我不建議你使用,因爲你是一個指針設置到STRING,而不是將其複製到某個地點。

當涉及到operator=它看起來很不錯,因爲我可以看到,如果你傳遞正確的數據..

編輯: 看其他評論說的拷貝構造函數,我沒扔一下。

複製構造它構造/讓一個實例相同的構造,所以如果你是動態的構造函數和類中的分配內存,那麼你應該做的是,在拷貝構造函數太..

// Ofcourse #include<cstring> 
class CMyString { 
public: 
CMyString(); 
CMyString(char* pData); 
CMyString(const CMyString& str); 
~CMyString(void); 

char* getData(); 
void setData(char* pData); 

CMyString& operator=(const CMyString& str); 

private: 
    char* m_pData; 
}; 

    CMyString::CMyString() { 
    m_pData = nullptr; // so it doesn't hang 
} 

CMyString::CMyString(char* pData) { 
    m_pData = new char[strlen(pData) + 1]; // allocates slots of memory with length of the string pData 
    strcpy(m_pData, pData) 
} 

CMyString::CMyString(const CMyString& str) { 
    m_pData = new char[strlen(str.m_pData) + 1]; 
    strcpy(m_pData, str.m_pData); 
    // Here you are constructing an instance so you should allocate memory for the dynamic string 
} 

CMyString::~CMyString(void) { 
    delete [] m_pData; // Since we allocated few slots 
} 

CMyString& CMyString::operator=(const CMyString& str) { 
    if (this == &str) 
     return *this; 

    delete [] m_pData; // Few slots of memory should be released 
    // m_pData = nullptr; No need for this since you are allocating after 
    m_pData = new char[strlen(str.m_pData) + 1]; 
    strcpy(m_pData, str.m_pData); 

    return *this; 
} 

char* CMyString::getData() { 
    return m_pData; 
} 

void CMyString::setData(char *pData) { 
    // m_pData = pData; Illegal don't get the address of a string make a copy of it (Don't point to a string you want a copy) 
    // If it isn't set. If it is, you will need to delete it 
    m_pData = new char[strlen(pData) + 1]; 
    strcpy(m_pData, pData); 
} 

可能有一些拼寫錯誤所以打我,如果有什麼需要編輯或添加..

注:測試=「字符串」是非法的,如果它是你的意圖(strcpy的)內容總是複製。如果人們離開是因爲我受限於當前的知識(仍然是新手),請查看其他評論。然而,我會盡力幫助..

重要提示:當分配嘗試瞭解它背後的概念,你想做什麼和你做了什麼。不要忘記刪除/刪除[] :) 祝你好運!

+0

我已經想通了^ _ ^。 – Poodar

+0

如果有什麼需要打我(剛完成這部分哈哈) –

0

那麼,你有一大堆的錯誤。只是不在operator=。你只有一個無意義的m_pData = nullptr;

new char分配一個字符和new char[30]分配一個30個字符的數組。指針是一樣的,你必須知道它是哪一個。每一個新的必須通過刪除和每個新的[]通過刪除[]來平衡。所以最好不要混淆兩者。使用new char[1]

的一些注意事項你的代碼的其餘部分:數組的

1)m_pData = str.m_pData;複製地址所以現在2類使用同一個陣列和陣列老永遠不會被釋放。

2)註釋掉析構函數中的delete是爲了防止內存泄漏,但應該是delete []。但是1使這不可能。

3)test2 = "23";使用不兼容的指針類型。 C字符串是const的,你的編譯器應該已經警告過你。

4)test2 = "23";複製數組的覆蓋值覆蓋舊值。舊數組是內存泄漏。

5)CMyString str(pData);導致pData的地址被複制到您的類中。 2中的delete []稍後會嘗試釋放它,但它永遠不會被new []分配。構造函數和setData應該像在operator =中那樣複製字符串。

6)看看std :: move,std :: uniq_ptr,std :: shared_ptr。