C++:从 children 中隐藏方法
C++: hide method from children
我有一个名为 transform
的 class,它的 child class、translation
、rotation
和 scaling
,应该对三角形应用变换。
每个 child classes 都会覆盖 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*
的列表传递给它以启用多态性。
我唯一的问题是现在 child classes 也知道这个方法。这让我很困扰,因为 child class 不应该应用所有其他转换。
有没有优雅的解决方案?
使 apply_transforms
成为一个非成员函数,它不包含在 类 实现 transform
所需的头文件中。
我建议稍微改变一下您查看变换的方式。
使 transform
成为 class,这样它就不需要从中派生出其他 classes。转换一个点需要的所有数据都可以保存在这个class.
添加构造缩放变换、平移变换和旋转变换的函数。
添加乘以变换的函数,乘以一个变换和一个点。这些可以是用于转换其他形状的构建块。
根据需要添加变换其他形状的功能。
以骨骼形式存在,
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;
事实是,由于您的 apply_transforms(...)
方法是 public,因此所有潜在调用者都可以使用它。考虑到这一点,您不能也不应该阻止 child class 们看到这些方法。
如果您知道您的方法将被特定的 classes 调用,您可以将您的方法设为私有并将那些调用 classes 的人声明为好友。
否则,将该方法封装在不同的 class 中,以防止 transform
的 child class 包含它。
我有一个名为 transform
的 class,它的 child class、translation
、rotation
和 scaling
,应该对三角形应用变换。
每个 child classes 都会覆盖 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*
的列表传递给它以启用多态性。
我唯一的问题是现在 child classes 也知道这个方法。这让我很困扰,因为 child class 不应该应用所有其他转换。
有没有优雅的解决方案?
使 apply_transforms
成为一个非成员函数,它不包含在 类 实现 transform
所需的头文件中。
我建议稍微改变一下您查看变换的方式。
使
transform
成为 class,这样它就不需要从中派生出其他 classes。转换一个点需要的所有数据都可以保存在这个class.添加构造缩放变换、平移变换和旋转变换的函数。
添加乘以变换的函数,乘以一个变换和一个点。这些可以是用于转换其他形状的构建块。
根据需要添加变换其他形状的功能。
以骨骼形式存在,
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;
事实是,由于您的 apply_transforms(...)
方法是 public,因此所有潜在调用者都可以使用它。考虑到这一点,您不能也不应该阻止 child class 们看到这些方法。
如果您知道您的方法将被特定的 classes 调用,您可以将您的方法设为私有并将那些调用 classes 的人声明为好友。
否则,将该方法封装在不同的 class 中,以防止 transform
的 child class 包含它。