【问题标题】:c++ assignment operator only working on objects already initialized [duplicate]c ++赋值运算符仅适用于已初始化的对象[重复]
【发布时间】:2021-03-01 08:24:22
【问题描述】:

您好,我的问题(至少看起来是这样)是我在声明变量时不能使用重载赋值运算符。我只能在对象已经包含一些值时使用它。

在我的测试文件中,我有以下代码行,它们没有按需要使用赋值运算符,并且会导致程序崩溃。

JumblePuzzle jp2("foo", "easy");
JumblePuzzle jp1 = jp2;
cout << "Attempted assignment" << endl;

但是,以下几行将起作用。

JumblePuzzle jp2("foo", "easy");
JumblePuzzle jp1("bar", "easy");
jp1 = jp2;
cout << "Attempted assignment" << endl;

JumblePuzzle 类

class JumblePuzzle{
public:
    JumblePuzzle(string word, string difficultyString);
    ~JumblePuzzle();
    JumblePuzzle(const JumblePuzzle &puzzle);


    charArrayPtr* getJumble() const;
    charArrayPtr* Jumble() const;
    int getSize() const;
    int getRowPos() const;
    int getColPos() const;
    char getDirection() const;
    bool placeWord();
    string getWord() const;

    JumblePuzzle& operator=(const JumblePuzzle &puzzle); //relevant

private:
    int size;
    char direction;
    string word;
    int rowPos;
    int colPos;
    char** jumble;
};

JumblePuzzle 构造函数,我唯一遇到的其他问题是内存分配给 jumble。

JumblePuzzle::JumblePuzzle(string word, string difficultyString){
    if(!difficultyString.compare("easy"))
        size = word.length() * 2;

    else if(!difficultyString.compare("medium"))
        size = word.length() * 3;

    else if(!difficultyString.compare("hard"))
        size = word.length() * 4;


    this->word = word;
    rowPos = 0;
    colPos = 0;
    direction = '\0';


    jumble = (char**) malloc(size*sizeof(char *));
    for(int i = 0; i < size; i ++)
        jumble[i] =(char*) malloc(size*sizeof(char));


    for(int i = 0; i < size; i ++){
        for(int j = 0; j < size; j ++){
            jumble[i][j] = '\0';
        }
    }
    while(!this->placeWord());
}

JumblePuzzle 复制构造函数

JumblePuzzle::JumblePuzzle(const JumblePuzzle &puzzle){
    size = puzzle.getSize();
    rowPos = puzzle.getRowPos();
    colPos = puzzle.getColPos();
    direction = puzzle.getDirection();
    word = puzzle.getWord();

    const charArrayPtr *tempJumble = puzzle.Jumble();
    jumble = (charArrayPtr*) malloc(size*size*sizeof(char));

    memcpy(jumble, tempJumble, size*size);
}

重载的赋值运算符

JumblePuzzle& JumblePuzzle::operator=(const JumblePuzzle &puzzle){

        cout << "in assignment operator" << endl;
        size = puzzle.size;
        direction = puzzle.direction;
        rowPos = puzzle.rowPos;
        colPos = puzzle.colPos;
        word = puzzle.word;


        jumble = (charArrayPtr*) malloc(size*sizeof(char *));
        for(int i = 0; i < size; i ++)
            jumble[i] = (char*) malloc(size*sizeof(char));
        jumble = puzzle.jumble;

        return *this;

}

此代码用于学校作业,我的教授不希望我们更改测试文件代码,这就是为什么我需要第一段代码才能工作。

我已经尝试寻找解决方案很长一段时间了,如果有人能提供一些见解,我将不胜感激。

【问题讨论】:

  • 尽管使用了= 字符,但初始化不是赋值。初始化创建一个对象,赋值替换已经存在的对象的值。 (C++ 中有许多符号和关键字具有多种含义,具体取决于它们出现的位置。)

标签: c++


【解决方案1】:
JumblePuzzle jp2("foo", "easy");
JumblePuzzle jp1 = jp2;
cout << "Attempted assignment" << endl;

程序崩溃是因为它使用了默认的复制构造函数,它直接将jumble指针从jp2复制到jp1;它们以 same 指针结束,当 both 析构函数尝试释放相同的内存时,代码会崩溃。

相比之下,

JumblePuzzle jp2("foo", "easy");
JumblePuzzle jp1("bar", "easy");
jp1 = jp2;
cout << "Attempted assignment" << endl;

“有效”,因为您手动实现了operator= 来分配 内存。但它仍然不正确,因为jp1 的构造函数已经分配了内存,你既不释放也不重用,你只是覆盖指针并造成内存泄漏。

为了解决这个问题,我强烈建议不要使用原始指针。 jumble 大概可以存储为 std::vector&lt;std::string&gt;,这将完全消除手动内存管理的需要,并使默认的复制构造函数自动正确运行。如果您需要自己管理内存,您将需要手写一个复制构造函数,并确保复制构造函数和复制赋值运算符 (operator=) 都正确分配(并且在这种情况下分配,解除分配)内存。如果您use the copy-and-swap idiom,则需要意识到您实际上并不需要手动实现两者。

【讨论】:

    猜你喜欢
    • 2014-11-20
    • 1970-01-01
    • 2012-03-11
    • 2020-08-17
    • 2011-10-30
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多