C++ 类对象复制构造函数和 operator=

Posted

技术标签:

【中文标题】C++ 类对象复制构造函数和 operator=【英文标题】:C++ class objects copy constructor and 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 【参考方案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

以上是关于C++ 类对象复制构造函数和 operator=的主要内容,如果未能解决你的问题,请参考以下文章

C++ 中类的默认成员函数的问题(构造函数、析构函数、运算符 =、复制构造函数)(默认 ctor、dtor、复制 ctor)

C++面试之 类string的构造函数拷贝构造函数和析构函数

c++类大四个默认函数-构造函数 析构函数 拷贝构造函数 赋值构造函数

c++ 复制构造函数和析构函数

C++复制构造函数和=号重载问题

C++:对象和类|| 类的构造函数与析构函数