c ++参数未传递给运算符重载<

时间:2018-04-17 10:13:11

标签: c++ object overloading operator-keyword

为类" State"创建运算符重载时,我重载的运算符没有初始化任何成员变量。

    bool operator<(const State m)const  
    {
       return (mDist < m.mDist);
    }

将状态添加到调用此运算符的优先级队列时,mDist的值未初始化

这是开始流程的代码

int row=0;
int col=0;
current.getBlank(row, col); // gets position of 0 in 3x3 int array


if (row > 0)
{   
    //creates a new state with current 3x3 array and postion of 0 as member variables
    State u(current, row, col); 
    u.swapUp();           // swaps 0 with position above it
    //n.findMDist(goal);  //calculates Manhattan distance from goal state
    nextMoves.push(u);    //push into queue
}

关于我应该检查什么的任何建议可能导致值传递给操作员超载?

编辑:

这是我的州级。

#pragma once
#ifndef STATE_H_
#define STATE_H_
#include<iostream>
#include <vector>

using namespace std;

const int SIZE = 3;

class State
{
private:
    int board[SIZE][SIZE];
    int blankRow;
    int blankCol;
    State *parent;
    State *goal;

public:
    State() 
    {
        int counter = 0;
        for (int i = 0; i < SIZE; i++)
            for (int j = 0; j < SIZE; j++)
            {
                setValue(i, j, counter);
                counter++;
            }
        int mDist = 0;
    }

    State(const State& s) 
    {
        for (int i = 0; i < SIZE; i++)
            for (int j = 0; j < SIZE; j++)
                board[i][j] = s.getValue(i, j);
    }
    State(const State& s, int r, int c, State *g) 
    {
        for (int i = 0; i < SIZE; i++)
            for (int j = 0; j < SIZE; j++)
                board[i][j] = s.getValue(i, j);
        blankRow = r;
        blankCol = c;
        goal = g;
        findMDist(*goal);
    }

    //get
    int mDist;


    //find
    void findMDist(State Goal);


    bool operator<( State m)const   
    {
        return (mDist < m.mDist);
    }

};

#endif

这是实施mDist的地方

void Game::next() {

int row=0;
int col=0;
current.getBlank(row, col);


if (row > 0)
{
    State u(current, row, col);
    u.swapUp();
    n.findMDist(goal);
    nextMoves.push(u);
}
if (row < 2)
{
    State d(current, row, col);
    d.swapDown();
    n.findMDist(goal);
    nextMoves.push(d);
}
if (col < 2)
{
    State n(current, row, col);
    n.swapRight();
    n.findMDist(goal);
    nextMoves.push(n);
}
if (col > 0)
{
    State n(current, row, col);
    n.swapLeft();
    n.findMDist(goal);
    nextMoves.push(n);
}
}

2 个答案:

答案 0 :(得分:2)

bool operator<( State m)const

这会传递值,因此会调用复制构造函数。这就是:

State(const State& s)
{
    for (int i = 0; i < SIZE; i++)
        for (int j = 0; j < SIZE; j++)
            board[i][j] = s.getValue(i, j);
}

这仅复制board。它完全忽略了通过复制所有其他成员变量来正确地完成其工作,包括有问题的mDist

因此,operator<最终会处理一个不完整的副本,其中多个成员变量未初始化,因此您可以通过随后读取它们来调用未定义的行为。

修正案是:

  • 实现一个适当的复制构造函数,即完成其工作,即复制所有成员变量,并在完成所有外部可见状态后保持相同。
  • 不要将值传递给复制构造函数,因为这会浪费资源和糟糕的语义。通过const&代替。

答案 1 :(得分:0)

  

关于我应该检查什么的任何建议可能导致价值观   传递给操作员超载?

当您将State的副本传递给operator<时,不会复制mDist。您可以将mDist = s.mDist;添加到复制构造函数中(实际上您可能还想添加它),但最好将const State传递给比较器:

bool operator<(State const &m) const   
{
    return (mDist < m.mDist);
}

同样在你的构造函数中,你有局部变量初始化int mDist = 0;这没有任何意义,因为它几乎立即超出了范围。我认为您的意思是mDist = 0;这会照顾您当前未初始化的成员mDist