2017-05-31 78 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包含它。