关于类 - 构造函数和析构函数的程序中的疑问

时间:2015-02-23 15:20:52

标签: c++

我已从网站复制此代码。 但我在理解它时遇到了问题。 请你帮我解决这些疑惑。 我把它们写成了评论。

#include<iostream>
using namespace std;
#include<cstring>
class strings
{
    char *m_string;   
    int m_length;
    public:
        strings(const char* str = "")    
        {
            m_length = strlen(str) + 1;

            m_string = new char[m_length];

            strncpy(m_string,str,m_length);

            m_string[m_length - 1] = '\0';/*1*/
        }
        ~strings()  /*2*/
        {
            delete[] m_string;

            m_string = 0;/*3*/
        }
        char* get()
        {
            return m_string;
        }
};

int main()
{
    strings cstring("Alex");
    cout << "Hi I am " << cstring.get();
    cout << "\nsup";
    strings cstrings1("Shady");
    cout << "\nyo " << cstrings1.get();
    return 0;
}
  1. 为什么代码要求我这样做。当我删除此行代码仍然完美无缺
  2. 他们为什么要使用析构函数?再一次不使用它似乎对程序有任何影响
  3. 当我刚使用delete关键字
  4. 时,这样做的用途是什么

    你们能否以简单的方式向我解释我真的使用析构函数?非常感谢你

2 个答案:

答案 0 :(得分:0)

1)确保字符串为空终止 - 请参阅http://www.cplusplus.com/reference/cstring/strncpy/,了解为何并非总是如此 2)它允许删除操作符释放分配的堆内存 - 否则你的程序将有内存泄漏 3)避免删除以前删除的内存的好习惯 - 这可以避免未定义的行为。

答案 1 :(得分:0)

这是如何滥用C ++中的C语言来产生危险的,容易出错的程序。不要将此作为如何有效编写C ++的示例。回答您的具体问题:

  1. 在这种情况下,显式终止C风格的字符串是没有意义的。如果你不知道输入是否足够小以适应数组,那么strncpy可能截断字符串,而不是在末尾放置零终止符;因此,如果您使用strncpy,则必须自行终止,或者如果被截断则采取其他操作。但是在这里你刚刚分配了一个足够大的数组,使用strlen进行测量。您也可以使用strcpymemcpystd::copy(假设输出数组足够大)而不是strncpy。或者,因为这是C ++而不是C,所以抛弃整个东西并使用std::string

  2. 需要析构函数来释放构造函数中分配的内存。否则你有内存泄漏。如你所说,这似乎没有效果 - 除非程序不断分配和泄漏内存,在这种情况下你最终会耗尽。您还需要定义或删除复制构造函数和复制赋值运算符(根据Rule of Three),否则该类无法复制。

  3. 这是毫无意义的,因为指针本身即将与类对象的其余部分一起被销毁。在某些情况下,如果指针将在delete之后继续存在,将其设置为null将允许您检查它是否指向任何内容。但是,除非你喜欢长时间的调试,否则你不应该使用指针来进行内存管理。使用智能指针或std::stringRAII类型。