使用模板创建子类
Creating subclass using templates
我有一个设计问题,我正在努力克服。让我们假设类结构和层次结构是正确的,我无法改变它。
我有一个名为BaseWidget的类。它具有内部嵌套类 Grid 和 Square。网格保持正方形向量。他们在那里是为了更好地组织绘画行为。BaseWidget 在其 Layout(( 方法中构造了 Grid 和 Squares 的向量。
现在我有子类化 BaseWidget 和类 DerivedWidget。派生小部件对类 BaseWidget::Square 有额外的绘图要求。因此,使用Derived::WidgetSquare对BaseWidget::Square进行子类化会很好,也很容易。
问题来自网格和正方形是在BaseWidget::OnLayout中构造的事实。因此,当创建正方形的网格向量时,我想说"在您正在填充的向量中使用派生方块而不是正方形"。
我相信我的解决方案是使用模板,但我不确定以什么身份。
class BaseWidget : public Widget
{
protected:
void Layout(void)
void Draw(canvas c);
class Square {
Square(Rect r) : region(r) {}
Rect region;
virtual void Draw(canvas c);
};
class Grid {
std::std::vector<shared_ptr<<Square>> squares;
Rect region;
void Draw(canvas c);
};
std::vector<Grid> m_grids;
};
void Parent::Layout {
m_grids.resize(num_grids);
for (int i=0; i<num_grids; ++i) {
m_grids[i].region = some_rect;
for (int j=0; j<num_squares; ++j) {
m_grids[i].m_squares.push_back(std::make_shared<Square>(some_other_rect));
}
}
}
void BaseWidget::Draw(Canvas c)
{
for (int i = 0; i < m_grids.size(); i++) {
m_grids.Draw(c);
}
}
void Grid::Draw(Canvas c)
{
// draw some stuff here
for (int i = 0; i < m_squares.size(); i++) {
m_squares[i].Draw(c);
}
}
void Square::Draw(Canvas c)
{
// draw some stuff here
}
// new class that extends parent
class DerivedWidget : public BaseWidget
{
protected:
/*
* This class wants to do some special drawing in addition to its parents drawing
*/
class DerivedSquare : public Square {
virtual void Draw(canvas c);
};
}
如果我正确理解了您的问题,那么您正在寻找类似以下内容的内容。请注意,我简化了类和方法,它应该只是一个概念证明:
struct BaseWidget
{
struct BaseSquare
{
virtual void draw()
{
// ... Drawing Logic for Base Square
}
};
virtual void draw()
{
drawInternal<BaseSquare>();
}
protected:
template <typename SquareType>
void drawInternal()
{
auto squareToDraw = std::make_shared<SquareType>();
squareToDraw->draw();
}
};
struct DerivedWidget : BaseWidget
{
struct DerivedSquare : BaseSquare
{
virtual void draw() override
{
// Drawing Logic for Dervied Square
}
};
virtual void draw() override
{
drawInternal<DerivedSquare>();
}
};
当然,这有一些重要的限制。首先,BaseWidget
类必须知道如何构造正方形,因此DerivedSquare
不能有一个花哨的构造函数。您可以通过将构造函数参数传递给drawInternal
函数来克服这个问题,但我不确定这是否适合您的设计。
似乎你只需要一个工厂,你可以为此添加一个虚拟方法:
class BaseWidget : public Widget
{
protected:
void Layout()
void Draw(canvas c);
class Square {
public:
Square(Rect r) : region(r) {}
Rect region;
virtual void Draw(canvas c);
};
class Grid {
public:
std::std::vector<shared_ptr<<Square>> squares;
Rect region;
void Draw(canvas c);
};
virtual std::unique_ptr<Square> MakeSquare() const { return std::make_unique<Square>(/*...*/); }
std::vector<Grid> m_grids;
};
// new class that extends parent
class DerivedWidget : public BaseWidget
{
protected:
/*
* This class wants to do some special drawing in addition to its parents drawing
*/
class DerivedSquare : public Square {
virtual void Draw(canvas c);
};
std::unique_ptr<Square> MakeSquare() const override { return std::make_unique<DerivedSquare>(/*...*/); }
}
并在代码中使用MakeSquare()
而不是硬编码Square
。
尝试这样的事情:
template <class Derived>
class BaseWidget : public Widget
{
// ...
class Grid {
std::std::vector<shared_ptr<<Derived::SquareType>> squares;
// ...
}
}
class DerivedWidget : public BaseWidget
{
using SquareType = DerivedSquare;
// ...
}
相关文章:
- 如何为定义的情况创建子类?
- 创建子类的多个实例,其中只有一个超类实例
- 创建一个函数,该函数使用模板创建类或子类的对象
- 在父类函数中创建子类 - 可能吗?
- 使用模板创建子类
- 创建子类复制构造函数时是否强制使用/创建默认的超级构造函数?[C++]
- 我如何告诉课程创建独特的子类
- 如何将字符串(ID)映射到新的子类对象C 的创建
- 创建 QQuickItem 子类的实例是否有问题,我不打算渲染或添加到 QML 树中的实例?
- C++:从两个包含子类 (typedef) 的列表创建一个列表
- C 如何用数组在类中创建子类
- 如何创建一个包含C 中的子类的类的链接列表
- 删除已创建的Qt元素和子类
- C++在子类中创建一个可用的方法
- 创建子类对象时, 是为超类创建的第二个对象
- 创建子类的向量
- C++:在父类中创建子类时出现问题
- C++ 从已初始化的父类创建子类
- 创建子类变量的语法
- 从超类创建子类