C++ OOP中调用方法返回后字段消失问题求助
问题:链式调用后StrokeColor字段为空
我尝试在变量a中获取Text类的引用以实现链式调用,但调用SetStrokeColor方法返回引用后,对应字段变为空值:
Text t = Text(base_text); auto a = t.SetStrokeColor("yellow");
相关类定义如下:
// 模板PathProps类(缺失模板参数声明) class PathProps { public: Owner &SetFillColor(Color color) { fill_color_ = color; return AsOwner(); } Owner &SetStrokeColor(Color color) { this->stroke_color_ = std::move(color); return AsOwner(); } Owner &SetStrokeWidth(double width) { stroke_width_ = width; return AsOwner(); } Owner &SetStrokeLineCap(StrokeLineCap strokeLineCap) { stroke_line_cap = strokeLineCap; return AsOwner(); } Owner &SetStrokeLineJoin(StrokeLineJoin strokeLineJoin) { stroke_line_join = strokeLineJoin; return AsOwner(); } void RenderAttrs(std::ostream &out) const { using namespace std::literals; if (fill_color_.has_value()) { out << " fill=\"" << *fill_color_ << "\""; } /*if (stroke_color_) { out << " stroke=\"" << *stroke_color_ << "\""; }*/ if (stroke_width_.has_value()) { out << " stroke-width=\"" << *stroke_width_ << "\""; } if (stroke_line_cap.has_value()) { out << stroke_line_cap; } if (stroke_line_join.has_value()) { out << stroke_line_join; } } protected: ~PathProps() = default; Color stroke_color_; std::optional<Color> fill_color_; std::optional<double> stroke_width_; std::optional<StrokeLineCap> stroke_line_cap; std::optional<StrokeLineJoin> stroke_line_join; private: Owner &AsOwner() { return static_cast<Owner &>(*this); } }; // Text类 class Text final : public Object, public PathProps<Text> { public: Text() = default; Text(const Text &); ~Text() override = default; Text &SetPosition(Point pos); Text &SetOffset(Point offset); Text &SetFontSize(uint32_t size); Text &SetFontFamily(std::string font_family); Text &SetFontWeight(std::string font_weight); Text &SetData(std::string data); [[nodiscard]]std::string replaceSpecialCharacters() const; private: Point TextCoordinates = {0, 0}; Point TextShifts = {0, 0}; uint32_t FontSize = 1; std::string FontWeight; std::string FontFamily; std::string text; void RenderObject(const RenderContext &context) const override; };
经调试发现,SetStrokeColor方法内部字段值正常,但外部调用后字段为空。
原因分析
- 变量声明未获取引用:
auto a = t.SetStrokeColor("yellow");中auto默认推导为值类型,会创建Text的拷贝对象而非持有原对象的引用,若拷贝构造未正确处理基类属性,新对象的stroke_color_会是默认空值。 - 拷贝构造函数未正确实现:
Text声明了拷贝构造但未实现,编译器无法自动完成基类PathProps成员的拷贝,导致拷贝对象丢失stroke_color_的值。 - PathProps缺少模板参数:代码注释标注为模板类,但未添加
template<typename Owner>声明,导致Owner标识符未定义,编译逻辑存在潜在错误。 - 属性类型不一致:
stroke_color_是Color类型,而非其他属性使用的std::optional<Color>,无法统一判断属性是否被设置,增加逻辑混乱风险。
解决办法
1. 修正变量声明,获取原对象引用
若需链式调用原对象,将变量声明为引用类型:
Text t = Text(base_text); auto& a = t.SetStrokeColor("yellow"); // a为t的引用,与原对象字段保持一致
2. 实现正确的拷贝构造函数
手动实现Text的拷贝构造,确保基类和派生类的所有成员都被正确拷贝:
Text::Text(const Text& other) : Object(other), PathProps<Text>(other), TextCoordinates(other.TextCoordinates), TextShifts(other.TextShifts), FontSize(other.FontSize), FontWeight(other.FontWeight), FontFamily(other.FontFamily), text(other.text) {}
3. 补全PathProps的模板类声明
添加模板参数声明,修正Owner未定义的问题:
template<typename Owner> class PathProps { // 原类内容保持不变 };
4. 统一属性类型(可选)
将stroke_color_改为std::optional<Color>,与其他属性保持一致,统一判断逻辑:
// PathProps的protected成员修改 std::optional<Color> stroke_color_;
同时修正RenderAttrs中的判断逻辑:
if (stroke_color_.has_value()) { out << " stroke=\"" << *stroke_color_ << "\""; }
内容的提问来源于stack exchange,提问作者Bonart
相关产品推荐
相关产品推荐

