C ++:隐藏来自孩子的方法

时间:2017-05-31 15:56:27

标签: c++ oop inheritance polymorphism information-hiding

我有一个名为transform的类及其子类translationrotationscaling,它们应该在三角形上应用转换。

每个子类都会覆盖apply_transform()方法:

class transform
{
protected:
    virtual triangle apply_transform(const triangle&) const = 0;
public:
    static triangle apply_transforms(const triangle&, const std::initializer_list<const transform*>&);
};

class scaling : public transform
{
...
public:
    triangle apply_transform(const triangle&) const override;
};

//same for rotation and translation

我还有一个名为apply_transforms的函数,它应该可以被外界访问,我用它来应用多个转换。我传递了一个transform*列表来启用多态。

我唯一的问题是,现在,子类也知道这种方法。这困扰我,因为子类不应该应用所有其他转换。

这有一个优雅的解决方案吗?

3 个答案:

答案 0 :(得分:4)

使onready.push(_=>alert("Wohoo!")); 成为非成员函数,该函数未包含在实现apply_transforms的类所需的头文件中。

答案 1 :(得分:2)

我建议您稍微改变查看转换的方式。

  1. 使transform成为一个类,使其不需要从中派生其他类。转换点所需的所有数据都可以保存在这个类中。

  2. 添加构造缩放变换,平移变换和旋转变换的函数。

  3. 添加函数以进行乘法变换,并将变换和点相乘。这些可以是用于转换其他形状的构建块。

  4. 根据需要添加转换其他形状的功能。

  5. 以骨架形式,

    class transform { ... };
    class position { ... };
    
    // tag structs
    struct rotation_about_x {};
    struct rotation_about_y {};
    struct rotation_about_z {};
    
    // Functions to construct transforms
    transform construct_scale_transform(double scale_factor) { ... };
    transform construct_translation_transform(position pos) { ... };
    transform construct_rotation_transform(double angle, rotation_about_x tag) { ... };
    transform construct_rotation_transform(double angle, rotation_about_y tag) { ... };
    transform construct_rotation_transform(double angle, rotation_about_z tag) { ... };
    
    // Function to transform a point.
    position operator*(transform const& t, position const& p) { ... }
    
    // Function to multiply transforms.
    transform operator*(transform const& t1, transform const& t2) { ... }
    
    
    // Functions to apply transforms to other objects.
    triangle operator*(transform const& tr, triangle const& t) { ... }
    ...
    

    用法:

    transform t1 = construct_rotation_transform(10, rotation_about_x{});
    transform t2 = construct_translation_transform({20, 10, 0});
    
    position p1{100, 200, 30};
    position p2 = t1*t2*p1;
    
    triangle tr1{ ... }
    triangle tr2 = t1*t2*tr1;
    

    如果要多次使用相同的组合变换,请首先计算组合变换并将其用于所有变换。

    transform t1 = construct_rotation_transform(10, rotation_about_x{});
    transform t2 = construct_rotation_transform(5, rotation_about_y{});
    transform t3 = construct_translation_transform({20, 10, 0});
    tranform tc = t1 * t2 * t3;
    
    position p1{100, 200, 30};
    position p2 = tc*p1;
    
    triangle tr1{ ... }
    triangle tr2 = tc*tr1;
    

答案 2 :(得分:1)

事实是,由于您的apply_transforms(...)方法是公开的,因此所有潜在的来电者都可以使用它。考虑到这一点,您不能也不应该阻止子类看到这些方法。

如果您知道将从特定类调用您的方法,则可以将您的方法设为私有,并将那些调用类声明为朋友。

否则,将该方法封装在另一个类中,以防止transform的子类包含它。