当前位置:嗨网首页>书籍在线阅读

14-应该和不应该

  
选择背景色: 黄橙 洋红 淡粉 水蓝 草绿 白色 选择字体: 宋体 黑体 微软雅黑 楷体 选择字体大小: 恢复默认

12.3.1 应该和不应该

下面的摘要包含了两个不正确的示例(指出什么是不应当做的)以及一个良好的构造函数示例:

String::String()
{
    str = "default string"; // oops, no new []
    len = std::strlen(str);
}
String::String(const char * s)
{
    len = std::strlen(s);
    str = new char;       // oops, no []
    std::strcpy(str, s);  // oops, no room
}
String::String(const String & st)
{
        len = st.len;
        str = new char[len + 1];  // good, allocate space
        std::strcpy(str, st.str); // good, copy value
}

第一个构造函数没有使用new来初始化str。对默认对象调用析构函数时,析构函数使用delete来释放str。对不是使用new初始化的指针使用delete时,结果将是不确定的,并可能是有害的。可将该构造函数修改为下面的任何一种形式:

String::String()
{
    len = 0;
    str = new char[1]; // uses new with []
    str[0] = '\0';
}
String::String()
{
    len = 0;
    str = 0; // or, with C++11, str = nullptr;
}
String::String()
{
    static const char * s = "C++"; // initialized just once
    len = std::strlen(s);
    str = new char[len + 1];       // uses new with []
    std::strcpy(str, s);
}

摘录中的第二个构造函数使用了new,但分配的内存量不正确。因此,new返回的内存块只能保存一个字符。试图将过长的字符串复制到该内存单元中,将导致内存问题。另外,这里使用的new不带中括号,这与另一个构造函数的正确格式不一致。

第三个构造函数是正确的。

最后,下面的析构函数无法与前面的构造函数正常地协同工作:

String::~String()
{
    delete str;        // oops, should be delete [] str;
}

该析构函数未能正确地使用delete。由于构造函数创建的是一个字符数组,因此析构函数应该删除一个数组。