C++一维生命游戏cell类引用初始化及指针引用使用问题求助
一维康威生命游戏Cell类设计问题
问题描述
我正在用C++编写一维康威生命游戏,想让cell类拥有分别指向右侧和左侧细胞的引用,但在代码结构设计、指针/引用的选择,以及&和*的具体用法上存在困惑。目前遇到的核心问题是:初始化一个cell对象时必须先初始化其左右两侧的cell,这显然无法实现——应该是循环依赖问题?
现有代码
class cell { private: const Vector2 size = {100.0, 100.0}; Vector2 position; cell &right; cell &left; public: cell(Vector2 in_position); std::vector<cell> get_pointers() { return {*right, *left}; } void set_pointers(cell &in_right, cell &in_left) { right = in_right; left = in_left; } }; cell::cell(Vector2 in_position) { position = {in_position.x - size.x/2, in_position.y - size.y/2}; }
报错信息
no operator "*" matches these operands
function "cell::operator=(const cell &)" (declared implicitly) cannot be referenced -- it is a deleted function
问题分析与解决方案
报错原因拆解
- 解引用运算符错误:
right和left是引用类型,不是指针,根本不需要用*解引用。直接写right就代表它绑定的cell对象,用*right相当于对一个cell对象再解引用,自然没有匹配的运算符。 - 拷贝赋值运算符被删除:C中,如果类包含引用成员,编译器会自动删除默认的拷贝赋值运算符(
operator=)。而你的set_pointers函数试图给引用赋值——但引用一旦初始化就无法改变绑定的对象,这是C的语法规则,所以这个操作非法。
核心解决方案:用指针替代引用
引用的特性是必须在构造时初始化,且绑定后无法更改,这正好和你的需求冲突(你需要先创建cell,再设置左右邻居)。换成指针就能解决这个问题:指针可以先初始化为nullptr,之后再指向其他cell对象,完美避开循环初始化的问题。
修改后的代码示例
#include <vector> // 假设Vector2的定义如下(如果已有定义可忽略) struct Vector2 { double x, y; }; class cell { private: const Vector2 size = {100.0, 100.0}; Vector2 position; // 用指针替代引用,默认初始化为nullptr cell* right = nullptr; cell* left = nullptr; public: // 使用成员初始化列表构造,更符合C++规范 cell(Vector2 in_position) : position{in_position.x - size.x/2, in_position.y - size.y/2} {} // 返回邻居指针的vector,避免拷贝原对象 std::vector<cell*> get_neighbors() { return {right, left}; } // 设置左右邻居指针 void set_neighbors(cell* in_right, cell* in_left) { right = in_right; left = in_left; } // 生命游戏需要的状态变量,示例用bool表示存活/死亡 bool is_alive = false; }; // 初始化一维细胞链的示例逻辑 int main() { const int cell_count = 5; std::vector<cell> cell_chain; // 第一步:先创建所有细胞,此时邻居指针都是nullptr for (int i = 0; i < cell_count; ++i) { // 按水平位置排列细胞 cell_chain.emplace_back(Vector2{static_cast<double>(i)*100.0, 0.0}); } // 第二步:遍历设置每个细胞的左右邻居 for (int i = 0; i < cell_count; ++i) { cell* left_neighbor = (i > 0) ? &cell_chain[i-1] : nullptr; cell* right_neighbor = (i < cell_count-1) ? &cell_chain[i+1] : nullptr; cell_chain[i].set_neighbors(right_neighbor, left_neighbor); } return 0; }
关键说明
- 指针 vs 引用:引用适合一旦绑定就不会改变的场景,指针适合需要动态变更指向的场景,你的生命游戏明显属于后者。
- 成员初始化列表:构造函数中用
:初始化成员变量是C++的最佳实践,比函数体内赋值更高效,也能避免一些潜在问题。 - 细胞链初始化逻辑:先批量创建所有细胞,再逐个设置邻居指针,彻底解决循环依赖问题——因为此时所有细胞都已经存在,只需要把它们的地址关联起来。
内容的提问来源于stack exchange,提问作者LWB
相关产品推荐
相关产品推荐

