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

C++父类方法调用子类方法 实现set_size同步调整matrix大小

实现方案

你要的调用链路本质是「父类通用逻辑执行完后,自动触发子类自定义逻辑」,C++里有两种成熟的实现方式,对应你保留继承、或者放弃继承两种需求:

方案1:保留继承结构,用虚函数实现多态回调

这个方案完全匹配你写的继承结构,核心是用模板方法模式:父类set_size固定执行「赋值宽高」的通用逻辑,留一个虚函数钩子给子类实现自定义逻辑,调用时会自动匹配到子类重写的钩子版本,刚好符合你要的Line调用Style的set_size -> Style执行完基础逻辑 -> 自动调用Line的matrix调整逻辑的链路。
直接上改完的可运行代码,顺便修了你原代码里的死循环bug:

Style.h

#pragma once
class Style
{
    public:
        void set_size(int width, int height);
    protected:
        int width = 0, height = 0;
        // 尺寸变更后的虚钩子,子类重写就能加自己的逻辑
        virtual void on_size_changed() {}
};

Style.cpp

#include "Style.h"
void Style::set_size(int width, int height)
{
    this->width = width;
    this->height = height;
    // 通用逻辑执行完,调用钩子,多态会自动路由到子类实现
    on_size_changed();
}

Line.h

#pragma once
#include "Style.h"
#include <vector>

class Line : public Style
{
    public:
        void draw();
    protected:
        // 重写父类的尺寸变更钩子
        void on_size_changed() override;
    private:
        std::vector<std::vector<char>> matrix;
};

Line.cpp

#include "Line.h"

void Line::on_size_changed()
{
    matrix.clear();
    // 直接用父类存好的宽高初始化matrix,填充'-'
    matrix.resize(height, std::vector<char>(width, '-'));
}

void Line::draw()
{
    // matrix已经在set_size时初始化完成,直接遍历渲染即可
    for (const auto& row : matrix)
    {
        for (char c : row)
        {
            putchar(c);
        }
        putchar('\n');
    }
}

Main.cpp

#include "Line.h"

int main()
{
    Line line;
    line.set_size(10, 10);
    // 此时line的matrix已经自动调整为10*10的尺寸
    line.draw();
    return 0;
}

提一句你原代码的bug:原来Line::draw里内层循环条件错写为j < Line::height,循环递增变量错写为i++,会直接触发死循环,上面的实现已经规避了这个问题。

方案2:放弃继承,用组合实现(更推荐的设计)

先说你担心的设计合理性问题:Line和Style本身不是「is-a(是一个)」的关系——Style是尺寸、颜色这类样式属性的集合,Line是具体的图形元素,图形元素是「拥有(has-a)」样式,而不是「是一种样式」,硬写继承耦合度很高,后续扩展很容易出问题,用组合的方式逻辑更直白,也不需要虚函数的额外开销。
组合实现的代码如下:

Style.h

#pragma once
class Style
{
    public:
        void set_size(int width, int height);
        int get_width() const { return width; }
        int get_height() const { return height; }
    private:
        int width = 0, height = 0;
};

Style.cpp

#include "Style.h"
void Style::set_size(int width, int height)
{
    this->width = width;
    this->height = height;
}

Line.h

#pragma once
#include "Style.h"
#include <vector>

class Line
{
    public:
        void set_size(int width, int height);
        void draw();
    private:
        // 把Style作为成员变量,而不是父类
        Style style;
        std::vector<std::vector<char>> matrix;
};

Line.cpp

#include "Line.h"

void Line::set_size(int width, int height)
{
    // 先调用样式对象的set_size存宽高
    style.set_size(width, height);
    // 同步调整matrix大小
    matrix.clear();
    matrix.resize(style.get_height(), std::vector<char>(style.get_width(), '-'));
}

void Line::draw()
{
    for (const auto& row : matrix)
    {
        for (char c : row)
        {
            putchar(c);
        }
        putchar('\n');
    }
}

这个方案的好处是逻辑完全透明,所有执行流程都在Line类内部可控,后续要加颜色、线宽等样式属性,只需要扩展Style类的接口就行,不会出现继承带来的方法污染、虚函数重写遗漏之类的问题。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.27 17:30:48