【问题标题】:C++ class objects copy constructor and operator=C++ 类对象复制构造函数和 operator=
【发布时间】:2019-08-15 05:15:51
【问题描述】:

我目前正在用 C++ 构建一个库。几天前我遇到了这个问题,我无法解决它。我已经缩短了代码,以便更容易看到。

下面是我的代码:

class String
{
private:
    mutable char* v;
    mutable int l = 0;
public:
    String()
    {
        l++;
        v = new char[1];
        *v = '\0';
    }
    String(const char* value)
    {
        int length = 0;
        while (value[length])
            length++;
        l = length + 1;
        v = new char[l];
        for (int i = 0; i < length; i++)
            v[i] = value[i];
        v[l - 1] = '\0';
    }
    String(const String& value)
    {
        int length = value.len();
        l = length + 1;
        v = new char[l];
        for (int i = 0; i < length; i++)
            v[i] = value[i];
        v[l - 1] = '\0';
    }

    int len() const
    {
        return l - 1;
    }

    char* val() const
    {
        return v;
    }

    char* operator=(const char* value) const
    {
        delete[] v;
        int length = 0;
        while (value[length])
            length++;
        l = length + 1;
        v = new char[l];
        for (int i = 0; i < length; i++)
            v[i] = value[i];
        v[l - 1] = '\0';
        return v;
    }
    char* operator=(const String& value) const
    {
        delete[] v;
        int length = value.len();
        l = length + 1;
        v = new char[l];
        for (int i = 0; i < length; i++)
            v[i] = value[i];
        v[l - 1] = '\0';
        return v;
    }

    char operator[](const int& index) const
    {
        return v[index];
    }
};

class StringArray
{
private:
    union ArrayDef
    {
    public:
        mutable String stringV;
        mutable int intV;

        ArrayDef()
        {
        }
        ArrayDef(const String& value)
            : stringV(value)
        {
        }
        ArrayDef(const int& value)
            : intV(value)
        {
        }
        ArrayDef(const ArrayDef& value)
        {
            intV = value.intV;
            stringV = value.stringV;
        }

        String operator=(const String& value) const
        {
            stringV = value;
            return stringV;
        }
        int operator=(const int& value) const
        {
            intV = value;
            return intV;
        }
        ArrayDef operator=(const ArrayDef& value)
        {
            intV = value.intV;
            stringV = value.stringV;
            return *this;
        }
    };
    mutable ArrayDef* arrdef;
    mutable int arrLen = 0;
public:
    StringArray()
    {
    }

    void add(const ArrayDef& value) const
    {
        ArrayDef temp[arrLen + 1];
        for (int i = 0; i < arrLen; i++)
            temp[i] = arrdef[i];
        temp[arrLen] = value;
        arrLen++;
        delete[] arrdef;
        arrdef = new ArrayDef[arrLen];
        for (int i = 0; i < arrLen; i++)
            arrdef[i] = temp[i];
    }

    int len() const
    {
        return arrLen;
    }

    ArrayDef val(const int& index) const
    {
        return arrdef[index];
    }
};

还有我的驱动代码:

#include <iostream>

int main()
{
    StringArray arr;
    arr.add(String("Hello"));
    arr.add(String("World"));
    std::cout << "Length of the array: " << arr.len() << std::endl;
    int indexOfString = 1;
    int indexOfCharacter = 2;
    char s = arr.val(indexOfString).stringV[indexOfCharacter];
    std::cout << "arr[" << indexOfString << "][" << indexOfCharacter << "]: " << s << std::endl;
}

我创建了两个类,即StringStringArray类。

对于String 类,出于安全问题,我需要始终在 char 指针数组后添加一个空字符。

对于StringArray 类,我使用联合,因为它实际上是多个类型的数组。

可以编译成功,但是输出一些随机字符,每次运行都不一样。

任何答案都将不胜感激,请告诉我为什么以及如何它不起作用。谢谢你。

来自,
海琴。

【问题讨论】:

  • 为什么所有数据成员都声明为mutable?为什么你的赋值运算符(其明确目的是修改对象的状态)声明为const

标签: c++ class oop object


【解决方案1】:

这段代码只是一些反模式的集合,很难研究。使内部数据可变的原因是什么?为什么你需要使用lengthl,有时是字符串的长度,有时是数组的大小?运算符operator= 返回char*,这是一种不好的做法。使用const int&amp; index 作为参数是一个奇怪的选择。您多次分配数组,但没有释放内存的析构函数。

这里你的赋值运算符返回一个值,而不是引用!

        ArrayDef operator=(const ArrayDef& value)
        {
            intV = value.intV;
            stringV = value.stringV;
            return *this;
        }

接下来是更危险的做法:

        // Recollect that this is a union
        ArrayDef(const ArrayDef& value)
        {
            intV = value.intV;
            stringV = value.stringV;
        }

您正在同时分配联合的两个字段!你是说struct吗?

尝试解决这个问题。首先将union 更改为structure

【讨论】:

  • 感谢您的回答。我真的没有发现我犯了这些错误。
【解决方案2】:

其中一个肯定不起作用的是 ArrayDef 复制构造函数和operator=(const ArrayDef &amp; value)。这是因为您只能在联合中使用活动值,而不能同时使用两者。这通常通过使用标记的联合来解决。您是否有不能使用标准模板库的原因?

#include <iostream>
#include <string>
#include <vector>

int main() {
    std::vector<std::string> arr;
    arr.push_back(std::string("Hello"));
    arr.push_back(std::string("World"));

    std::cout << "Length of the array: " << arr.size() << std::endl;

    constexpr int indexOfString = 1;  // second string - starting from 0!
    constexpr int indexOfCharacter = 2;  // third character

    char s = arr.at(indexOfString).c_str()[indexOfCharacter];  // using interfaces closest to the original

    std::cout << "arr[" << indexOfString << "][" << indexOfCharacter << "]: " << s << std::endl;
}

【讨论】:

  • 是的,你是对的。由于一些技术问题,我无法使用 STL
猜你喜欢
  • 1970-01-01
  • 2021-05-13
  • 2013-04-04
  • 1970-01-01
  • 2011-01-20
  • 1970-01-01
  • 1970-01-01
  • 2015-12-05
  • 1970-01-01
相关资源
最近更新 更多