gpt4 book ai didi

c++ - 如何传递 unique_ptr 来设置我的对象的成员变量?

转载 作者:行者123 更新时间:2023-11-28 01:24:33 26 4
gpt4 key购买 nike

我正在编写一个国际象棋应用程序。 Board 类包含一个Square 数组,每个方 block 可以容纳一个Piece。类型特定的类(PawnRook 等)继承自 Piece

为了实现这一点,Square 有一个指向特定Piece 的成员变量(它占用了那个Square)。

我遇到的问题是,当我尝试设置 Board 时,我无法将我创建的 unique_ptr 分配给成员变量广场

下面是函数调用的一般流程:

void Board::setBoard()
{
// White Pawn Placement
std::unique_ptr<Piece> wp1 = std::make_unique<Pawn>(PAWN, WHITE);
Board::setPiece("a2", wp1);
}

Pawn::Pawn(Type t, Color c) : Piece(t, c) {}

void Board::setPiece(const std::string &coords, std::unique_ptr<Piece> piece)
{
squareMap[coords].setPiece(piece);
}

void Square::setPiece(std::unique_ptr<Piece> piece)
{
Square::piece = std::move(piece);
}

当我尝试在包含 Board::setPiece("a2", wp1);

的行进行编译时,我收到以下错误
error: call to implicitly-deleted copy constructor of 'std::unique_ptr<Piece>'

不用说,有点啰嗦。

网上有一些关于继承、抽象类、如何使用 unique_ptr 等的很好的文档,但我一直无法弄清楚所有这些东西是如何组合在一起的。

所以,问题:

如何创建一个对象,将其分配给一个 unique_ptr,然后使用该 unique_ptr 设置另一个对象的成员变量?

以下是每个类的头文件,以防万一。请原谅我的问题的长度。我已经尽可能地缩短了。

Board.hpp

class Board {
public:
Board();
void printBoard();
Piece getPiece(const std::string &coords);
void setPiece(const std::string &coords, std::unique_ptr<Piece> piece);
~Board();
...
};

Square.hpp

class Square
{
public:
void setPiece(std::unique_ptr<Piece> piece);
Piece* getPiece() const;
protected:
std::unique_ptr<Piece> piece;
...
};

Piece.hpp

class Piece
{
public:
Piece();
Piece(Type, Color);
virtual bool movePiece() = 0; // abstract class
protected:
Color color;
Type type;
bool moved;
...
};

Pawn.hpp

class Pawn : public Piece
{
public:
Pawn(Type t, Color c);
bool movePiece() override;
};

最佳答案

问题是您在std::unique_ptr 对象按值 传递时没有使用std::move(),所以您正在尝试复制它们而不是移动它们。 std::unique_ptr 不能从中复制,只能从中移动,否则单一所有权语义将被破坏。这就是使 std::unique_ptr “唯一”的原因 - 一次只有 1 个 std::unique_ptr 可以引用内存中的给定对象。

尝试更像这样的东西:

class Pawn : public Piece
{
public:
Pawn(Color c);
...
};

Pawn::Pawn(Color c) : Piece(PAWN, c) {}

class Square
{
public:
...

// for accessing the current Piece without moving it around the Board
// (for printing, drawing, etc)...
const Piece* getPiece() const;

// for moving Pieces around the Board...
std::unique_ptr<Piece> setPiece(std::unique_ptr<Piece> piece);

...

protected:
std::unique_ptr<Piece> piece;
...
};

const Piece* Square::getPiece() const
{
return piece.get();
}

std::unique_ptr<Piece> Square::setPiece(std::unique_ptr<Piece> piece)
{
std::unique_ptr<Piece> old = std::move(this->piece);
this->piece = std::move(piece);
return std::move(old);
}

class Board {
public:
...

// for accessing a current Piece without moving it around the Board
// (for printing, drawing, etc)...
const Piece* getPiece(const std::string &coords) const;

// for moving Pieces around the Board...
std::unique_ptr<Piece> setPiece(const std::string &coords, std::unique_ptr<Piece> piece);

...

protected:
std::map<std::string, Square> squareMap;
...
};

void Board::setBoard()
{
...

// White Pawn Placement
std::unique_ptr<Piece> wp1 = std::make_unique<Pawn>(WHITE);
setPiece("a2", std::move(wp1));

// or simply:
//setPiece("a2", std::make_unique<Pawn>(WHITE));

...
}

const Piece* Board::getPiece(const std::string &coords) const
{
auto iter = squareMap.find(coords);
return (iter != squareMap.end())
? iter->second.getPiece()
: nullptr;
}

std::unique_ptr<Piece> Board::setPiece(const std::string &coords, std::unique_ptr<Piece> piece)
{
return squareMap[coords].setPiece(std::move(piece));
}

这允许 Square 维护当前分配给它的任何 Piece所有权,并且该所有权被转移 只有当一个新的 Piece 被分配时(例如,将捕获的 Piece 移动到另一个列表,当 Pawn 被提升时被回收).

关于c++ - 如何传递 unique_ptr 来设置我的对象的成员变量?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54543496/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com