0

我们的教授在网上发布了一个自定义的'String'模板文件,并要求我们填写以下功能。我的问题是,为了尝试理解这一点,为什么前三个构造函数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;
};
4

3 回答 3

6

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

  • 它在派生类中变得非常讨厌。想想看。
  • 很难使异常安全。
  • 启动也效率低下(需要默认构造然后分配)。

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

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


然而,另一种方式,即在复制构造方面实现复制分配,是非常常见的,被称为复制和交换习语

它很简单,异常安全且通常有效,如下所示:

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

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

是的,就是这样。

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

于 2013-03-13T20:28:26.247 回答
1

这只是一种将通用代码分解为辅助函数的方法。在这种情况下,operator=()充当辅助函数。它的功能是释放当前字符串(在本例中为NULL)并执行右侧的深层复制。

我觉得每个人都应该说Text = the_input_parameter

因为String(const String& source)这不是source正确的类型,所以无法编译。

因为String(const char* text)这是不正确的,因为这只会分配指针而不是执行深层复制。

以上假设您只向我们展示了类的一部分,并且实际的类定义了适当的赋值运算符和析构函数。如果没有,你需要一个新教授。

于 2013-03-13T20:17:44.983 回答
0

该类管理内存,因此析构函数释放它,赋值运算符为新数据分配新数据并释放旧数据(应该按此顺序)。

那么初始赋值的解释就很清楚了:你需要将成员字段初始化为一个正确的值,否则它将包含垃圾(一些指向某处的指针),代码将尝试使用和释放。

虽然从代码中看不到,但也可能有赋值const String&和类型转换运算符operator const char *() const

于 2013-03-13T20:35:20.400 回答