2017-04-02 77 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。