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

从派生类构造函数向基类构造函数传递引用的问题

C++基类持有外部结构体引用的问题与解决

问题描述

希望在Derived类的初始化列表中让Base类持有Coord结构体的引用,但传递Coord实例给Derived构造函数时,会创建新的Coord实例——无法从派生类更新外部的coord对象。请问这种传递引用的方式是否违规,还是做法有误?

示例代码

#include <iostream>

struct Coord{
  int x = 1;
  int y = 1;
  void printCoord(){
    std::cout << "X: " << x << " Y: " << y << std::endl;
  }
};

class Base{

  public:
  Coord myCoord;
  Base(Coord &coord): myCoord(coord){} // How do I modify this line so Base gets a copy of myCoord?
  virtual void updateCoord(int x, int y){};

};

class Derived : public Base {

  public:
  Derived(Coord &coord): Base(coord){} // Or possibly this line?
  virtual void updateCoord(int x, int y){ 
    myCoord.x = x;
    myCoord.y = y;  
    std::cout << "Updated to:" << std::endl;
    myCoord.printCoord();
  }
};

int main(){
  Coord myCoord;
  Base *baseptr;
  Derived d(myCoord);
  baseptr = &d;

  std::cout << "Before update:" << std::endl;
  myCoord.printCoord();
  baseptr->updateCoord(2,2);
  std::cout << "After update:" << std::endl;
  myCoord.printCoord();

  return 0;
}

预期输出

Before update:
X: 1 Y: 1
Updated to:
X: 2 Y: 2
After update:
X: 2 Y: 2

实际输出

Before update:
X: 1 Y: 1
Updated to:
X: 2 Y: 2
After update:
X: 1 Y: 1

问题根源与解决方法

问题原因

Base类中的myCoord是成员对象而非引用,构造函数初始化列表中的myCoord(coord)执行的是拷贝构造操作——将传入的外部Coord实例复制了一份存储在Base内部。后续Derived类的updateCoord修改的是这份内部拷贝,自然不会影响外部的Coord对象。

修正方案

将Base类中的myCoord改为引用类型,让它绑定到外部传入的Coord实例,而非创建拷贝:

修改后的完整代码

#include <iostream>

struct Coord{
  int x = 1;
  int y = 1;
  void printCoord(){
    std::cout << "X: " << x << " Y: " << y << std::endl;
  }
};

class Base{

  public:
  Coord& myCoord; // 修改为引用类型
  // 初始化列表绑定传入的引用
  Base(Coord &coord): myCoord(coord){} 
  virtual void updateCoord(int x, int y){};

};

class Derived : public Base {

  public:
  Derived(Coord &coord): Base(coord){} 
  virtual void updateCoord(int x, int y){ 
    myCoord.x = x;
    myCoord.y = y;  
    std::cout << "Updated to:" << std::endl;
    myCoord.printCoord();
  }
};

int main(){
  Coord myCoord;
  Base *baseptr;
  Derived d(myCoord);
  baseptr = &d;

  std::cout << "Before update:" << std::endl;
  myCoord.printCoord();
  baseptr->updateCoord(2,2);
  std::cout << "After update:" << std::endl;
  myCoord.printCoord();

  return 0;
}

关键说明

  1. 引用成员的初始化:C++中引用成员必须在构造函数的初始化列表中完成绑定,不能在构造函数体内赋值,所以Base的构造函数必须用myCoord(coord)来绑定外部传入的Coord引用。
  2. 生命周期注意事项:必须保证外部的Coord对象(如main中的myCoord)的生命周期长于Base/Derived对象,否则会出现悬空引用问题,导致未定义行为。

修改后运行代码,实际输出将与预期一致。

内容的提问来源于stack exchange,提问作者BooleanSmith

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.05 02:42:41