简体   繁体   中英

C++ class objects copy constructor and operator=

I'm currently building a library In 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.

For String class, I need to always add a null character after the char pointer array for safety issue.

For StringArray class, I uses union because it's actually an array for multiple types.

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? The operator operator= returns char* which is a bad practice. Using const int& index as a parameter is a strange choice. 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 ?

Try to fix that. Start with changing union to structure .

One of the things that certainly will not work is the ArrayDef copy constructor and 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;
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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