c++ - 带智能指针的段错误
问题描述
我目前正在尝试使用智能指针,但在尝试访问 getColor() 时遇到了段错误?
有人能说出我错过了什么吗?(对于理解板的定义如下:std::unique_ptr board [HEIGHT][WIDTH];)
std::unique_ptr<Piece> current (new Pawn(Color::WHITE));
this->board[1][1] = std::move(current);
if(this->board[1][1].get() == nullptr){
Log::debug("is nullptr");
return;
}
if(this->board[1][1].get()->getColor() == Color::BLACK){
Log::debug("Black");
} else{
Log::debug("White");
}
谢谢
解决方案
你的问题没有提供很多细节。但是我能够对其进行编码并在没有段错误的情况下运行它。
#include <memory>
#include <fmt/core.h>
constexpr std::size_t HEIGHT {8};
constexpr std::size_t WIDTH {8};
enum class Color {
WHITE, BLACK
};
struct Piece {
explicit Piece(Color color) : color_(color) {}
Color getColor() const {
return color_;
}
Color color_;
};
struct Pawn : public Piece {
explicit Pawn(Color color) : Piece(color){
}
};
struct Board {
std::unique_ptr<Piece> board [HEIGHT][WIDTH];
void set() {
std::unique_ptr<Piece> current(new Pawn(Color::WHITE));
this->board[1][1] = std::move(current);
if (this->board[1][1].get() == nullptr) {
fmt::print("is nullptr");
return;
}
if (this->board[1][1].get()->getColor() == Color::BLACK) {
fmt::print("Black");
} else {
fmt::print("White");
}
}
};
int main() {
Board b;
b.set();
}
更新
这是一个我更喜欢的版本:https ://godbolt.org/z/z6rfav
变体与继承
我没有继承Piece
,而是制作PieceType
了std::variant
所有可能类型的棋子(Pawn,Queen,King,...)。这是可能的,因为这组片段是封闭的:我们在编译时知道所有可能的片段。
enum class Color { WHITE, BLACK };
struct Pawn {};
struct King {};
using PieceType = std::variant<Pawn, King>; // extend to all pieces
struct Piece {
Piece(PieceType type, Color color) : color_(color), type_(type) {}
Color getColor() const { return color_; }
Color color_;
PieceType type_;
};
std::array
vs 不安全的 C 数组
我将board
from的定义切换std::unique_ptr<Piece> board[8][8]
到std::array<std::array<Piece, 8>, 8>
。这是更安全、更惯用的 C++。
空指针与可选
而不是使用 unique_ptr 来表示字段是否为空。我用std::optional
.
std::array<std::array<std::optional<Piece>, WIDTH>, HEIGHT> board_;
// Could be written as
using Field = std::optional<Piece>;
using Row = std::array<Field, WIDTH>;
using Board = std::array<Row, HEIGHT>;
Board board_;
推荐阅读
- c# - C# XML 多个子子项
- java - 在流中找到比最大值少几次的值
- terraform - 使用预安装的 Terraform 插件,而不是使用 terraform init 下载它们
- hashicorp-vault - 保险柜:如何创建秘密 ID
- java - 将资源文件夹中的 JAR 添加到 Maven 中的类路径
- python - Pandas:删除具有 nan 值索引的行
- wpf - 使用文本大小放大单选按钮和复选框项目符号绑定
- r - r - 将 filter() 应用于 data.frame 的难度
- asp.net - 如何使用asp.net和angularJS将文件Excel导入数据库中的多个表?
- riscv - 如何监测火箭芯的性能?