2017-05-31 49 views
2

我有一个叫做transform的类,它的子类translation,rotationscaling,它们应该应用于三角形的变换。C++:隐藏儿童的方法

每个子类中重写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*的列表来启用多态。

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

有没有一个优雅的解决方案呢?

+1

那么,你要么具有外部世界可见的功能(其中包括派生类),要么将其隐藏给每个人。 – DeiDei

+0

可以apply_transforms三角形类上的公共静态? –

+1

我建议你不要再为此烦恼了。你困扰我的字符串类,它与几何无关,也可以访问这个函数吗? –

回答

4

使apply_transforms成为不包含在实现transform的类所需的头文件中的非成员函数。

2

我建议改变一下你如何查看变换。

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

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

  3. 添加函数来乘法变换,并乘以一个变换和一个点。这些可以是用于转换其他形状的构件。

  4. 根据需要添加用于转换其他形状的函数。


在骨骼形态,

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; 
+1

但请注意,使用“*”的“自然”语法在C++中始终是从左到右的关联,这可能是低效的:https://en.wikipedia.org/wiki/Matrix_chain_multiplication –

+0

@BenVoigt,好点。幸运的是,您可以计算一个组合的变换,并根据需要多次使用它。 –

1

事实是,因为你的apply_transforms(...)方法是公共的,这是因为这样可以向所有潜在呼叫者。考虑到这一点,你不能也不应该阻止孩子们看到这些方法。

如果您知道您的方法将从特定类中调用,则可以使您的方法保持私有状态,并将这些调用类声明为朋友。

否则,将方法封装在不同的类中以防止子类transform包含它。