You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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


问题分析与解决方案

报错原因拆解

  1. 解引用运算符错误:right和left是引用类型,不是指针,根本不需要用*解引用。直接写right就代表它绑定的cell对象,用*right相当于对一个cell对象再解引用,自然没有匹配的运算符。
  2. 拷贝赋值运算符被删除: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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.25 04:23:09