Search code examples
c++classtemplatesmethods

Field disappears afrer return from method(C++ OOP)


Here I'm trying to get in variable "a" a reference for "Text" class (it's necessary for chain method), but after returning reference from value set field just becomes empty:

Text t = Text(base_text);
auto a = t.SetStrokeColor("yellow");

Here is definition of Text class with templates and so on:

//template PathProps class
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
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;
};

I debugged this and noticed that value in the method works properly but out of it doesn't


Solution

  • auto a = t.SetStrokeColor("yellow");
    

    This takes the reference that's returned from SetStrokeColor, and makes a copy of the referenced object, which becomes this a. This a is not a reference.

    You obviously want a to be a reference, so this should be:

    auto &a = t.SetStrokeColor("yellow");