c++ - 为什么这个构造函数要这样写?

标签 c++ object copy-constructor default-constructor c-strings

我们的教授在网上发布了一个自定义的“字符串”模板文件,不久前要求我们填写下面的函数。为了尝试理解这一点,我的问题是为什么前三个构造函数具有 Text = NULL; 而在其下方是 this = source;,它的其他形式.我觉得每个人都应该说 Text = the_input_parameter

非常感谢,这是代码:

class String
{
public:
    // Default constructor
    String()
    {
        Text = NULL;
    }
    String(const String& source)
    {
        Text = NULL;
        // Call the assignment operator to perform deep copy
        *this = source;     
    }
    String(const char* text)
    {
        Text = NULL;
        // Call the assignment operator to perform deep copy

        *this = text;

    }
~String()
    {
        delete[] Text;
    }

    // Assignment operator to perform deep copy
    String& operator = (const char* text)
    {
        // Ddispose of old Text
        delete[] Text;

        // +1 accounts for NULL-terminator
        int trueLength = GetLength(text) + 1;

        // Dynamically allocate characters on heap
        Text = new char[trueLength];

        // Copy all characters from source to Text; +1 accounts for NULL-terminator
        for ( int i = 0; i < trueLength; i++ )
            Text[i] = text[i];

        return *this;
    }

    // Returns a reference to a single character from this String
    char& operator [] (int index) const
    {
        int length = GetLength();

        // Check for valid index
        if ( (index < 0) || (index > length) )
        {
            stringstream error;
            error << "operator[] - index " << index << " is out of bounds (0.." << (length - 1) << ")";
            throw String(error.str().c_str());
        }

        return Text[index];
    }
private:
    // The encapsulated C-string
    char* Text;
};

最佳答案

为什么不应该在赋值方面实现构造函数:

  • 它在派生类中变得非常讨厌。考虑一下。
  • 很难使异常安全。
  • 它的启动效率也很低(需要默认构造然后赋值)。

所以在你的示例代码中为什么这样做的答案可能是你的教授对 C++ 编程一无所知。

否则,很难说:这样做根本没有任何意义。


然而,采用另一种方式,即根据复制构造实现复制分配,这种做法非常普遍,被称为 copy-and-swap 惯用语

它很简单,异常安全且通常有效,并且是这样的:

class Foo
{
public:
    void swap_with( Foo& other ) throw()
    {
        // No-throwing swap here.
    }

    void operator=( Foo other )
    {
        other.swap_with( *this );
    }
};

是的,就这些。

变体包括将交换器命名为 swap,让赋值运算符返回一个引用,有些更喜欢通过引用传递参数,然后制作一个拷贝(使用复制构造)。

关于c++ - 为什么这个构造函数要这样写?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15395602/

相关文章:

c++ - 基类中删除的构造函数是否影响子类?

c++ - 咖啡转换图像集 : symbol lookup error

c++ - Qtcreator GUI : how to modify highlighted entries' appearance?

c++ - is_Detected 可以使用哪些类型的模板?

Javascript:编辑对象属性会更改不同对象的属性

javascript - 在 JavaScript 中按对象参数过滤和计数对象的 JSON 对象

javascript - 获取对象属性的长度,该对象属性是对象数组的属性

c++ - constexpr 和可变成员以及隐式复制构造函数

c++ - enable_shared_from_this 的双重继承

c++ - 仅手动定义部分复制构造函数和赋值运算符