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
相关产品推荐
相关产品推荐

