简体   繁体   English

C++ 类对象复制构造函数和运算符=

[英]C++ class objects copy constructor and operator=

I'm currently building a library In C++.我目前正在用 C++ 构建一个库。 I have met this problem few days ago and I'm unable to fix it.几天前我遇到了这个问题,我无法修复它。 I have shorten the code so it can be seen easier.我已经缩短了代码,所以它可以更容易地看到。

Below is my code:下面是我的代码:

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];
    }
};

And my driver code:还有我的驱动程序代码:

#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;
}

I have created two class, that is, String and StringArray class.我创建了两个类,即StringStringArray类。

For String class, I need to always add a null character after the char pointer array for safety issue.对于String类,为了安全问题,我需要始终在 char 指针数组之后添加一个空字符。

For StringArray class, I uses union because it's actually an array for multiple types.对于StringArray类,我使用 union 是因为它实际上是多个类型的数组。

It can be successfully compiled but it output some random character and it is different every time I run it.它可以成功编译,但它输出一些随机字符,每次运行它都不同。

Any answers will be appreciated, and please tell me why and how it don't works.任何答案将不胜感激,请告诉我为什么以及如何不起作用。 Thank you.谢谢你。

From,从,
HaiQin.海琴。

This code is just a collection of antipatters that makes it difficult to study.这段代码只是一个反模式的集合,很难研究。 What is the reason of making the internal data mutable?使内部数据可变的原因是什么? Why do you need to play with length and l where sometimes it is the length of the string, sometimes it is the size of array?为什么你需要玩lengthl有时它是字符串的长度,有时它是数组的大小? The operator operator= returns char* which is a bad practice.运算符operator=返回char*这是一种不好的做法。 Using const int& index as a parameter is a strange choice.使用const int& index作为参数是一个奇怪的选择。 You allocate arrays multiple times but you have no destructor that frees the memory.您多次分配数组,但没有释放内存的析构函数。

Here your assignment operator returns a value, not reference!这里您的赋值运算符返回一个值,而不是引用!

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

Next comes even more dangerous practice:接下来是更危险的做法:

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

You are assigning both fields of the union at the same time!您正在同时分配联合的两个字段! Did you mean struct ?你是说struct吗?

Try to fix that.尝试解决这个问题。 Start with changing union to structure .从将union更改为structure

One of the things that certainly will not work is the ArrayDef copy constructor and operator=(const ArrayDef & value) .肯定行不通的一件事是 ArrayDef 复制构造函数和operator=(const ArrayDef & value) This is because you may only use the active value in the union, not both at the same time.这是因为您只能在联合中使用活动值,而不能同时使用两者。 This is usually solved by using a tagged union.这通常通过使用标记联合来解决。 Is there a reason you cannot use the Standard Template Library?是否有不能使用标准模板库的原因?

#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;
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM