C++中能否在一个对象的成员方法内调用另一对象的构造函数
问题结论
不能在普通成员函数内部直接调用成员类的构造函数完成成员对象初始化,你给出的示例代码会直接编译报错。
核心原因
C++类实例的构造顺序有严格规定:
- 当你创建
MainProg类的对象时,会先按声明顺序构造所有基类(也就是你说的父类)部分 - 紧接着按成员在类里的声明顺序,构造所有非静态成员对象——你代码里的
Data dataobj就是在这一步完成构造的,这一步发生在MainProg构造函数的函数体执行之前,更不可能延后到dataInput()这种普通成员函数执行时才做。 - 你在
dataInput()里写的dataobj(datalist);根本不是构造调用:此时dataobj已经是构造完成的对象,这行代码的语义是调用dataobj的operator()(datalist)仿函数方法,而你的Data类没有定义这个运算符,编译器会直接抛出错误。
符合需求的正确实现方式
你想要“先读取输入数据,再用读到的数据初始化Data成员”的逻辑完全可以实现,选下面任意一种方案即可:
方案1:给Data增加赋值/初始化接口
给Data补充默认构造函数,等读完数据后通过赋值或者初始化接口给对象设值,修正后的示例代码:
#include <iostream> class Data{ public: // 补默认构造函数,代表无参数的初始空状态 Data() = default; Data(int par) : par_(par) {} void setPar(int par) { par_ = par; } int getPar() { return par_; } private: int par_; // 其他成员变量 }; class MainProg{ public: MainProg() = default; void dataInput(); void dataProcess(); void dataOutput(); // 原代码此处误写为冒号 private: Data dataobj; // 这里会先调用Data的默认构造,处于空状态 }; void MainProg::dataInput(){ int read_par = 0; // 模拟读数据逻辑 std::cin >> read_par; // 方法A:调用setPar设置参数 dataobj.setPar(read_par); // 方法B:直接赋值,构造临时Data对象后移动赋值给dataobj // dataobj = Data(read_par); }
方案2:用智能指针延迟构造Data对象
如果你不想让Data存在默认构造的空状态,可以把成员改成智能指针,等读到数据后再真正构造Data实例:
#include <memory> #include <iostream> class Data{ public: // 不需要默认构造函数 Data(int par) : par_(par) {} int getPar() { return par_; } private: int par_; // 其他成员变量 }; class MainProg{ public: MainProg() = default; void dataInput(); void dataProcess(); void dataOutput(); private: // 初始是空指针,没有构造Data对象 std::unique_ptr<Data> dataobj; }; void MainProg::dataInput(){ int read_par = 0; std::cin >> read_par; // 读到数据后才真正构造Data实例 dataobj = std::make_unique<Data>(read_par); }
内容的提问来源于stack exchange,提问作者YS_Jin
相关产品推荐
相关产品推荐

