Bjarne Stroustrup建议使用反映真实概念(单位等)的类型而不是使用原语。例如here,他建议使用“Point”类型而不是两个整数。
这种方法的好处很明显。这意味着编译器可以确保参数具有相同的概念类型,而不仅仅是内存中的相同表示。 Stroustrup给出的一个例子是确保物理值在相同的单位。
我的问题是如何在实践中这样做。创建一个类型Point
等新类并不困难,但后来我添加了一个第三方库,它有自己的Point
对象,当然不能从其中构建一个矿。如果我包含第二个库,然后是第3个库,则问题会成倍增加。
人们在实践中采取了哪些方法解决这个问题?有优雅的解决方案吗?
答案 0 :(得分:4)
首先要尝试使用您使用的库的功能,而不是自己创建。
如果这是不可能的,并且您希望与库中的类似类兼容,则可以构建从库中获取类的构造函数和赋值运算符,并在构造自己的对象时使用其中的数据。
像
这样的东西namespace my_project
{
class my_point
{
public:
my_point(int x_, int y_)
: x(x_), y(y_)
{}
// Constructor taking a foreign library type
my_point(const OtherLibrary::Point& other)
: x(other.GetX()), y(other.GetY())
{}
// Copy-assignment operator taking foreign library type
my_point& operator=(const OtherLibrary::Point& other)
{
x = other.GetX();
y = other.GetY();
return *this;
}
private:
int x;
int y;
};
}
答案 1 :(得分:1)
当管理来自多个源(即来自各个第三方库的Point
类)的概念类似的数据类型时,我的直接想法是建立一个所有数据类型实现的接口,并使用它接口而不是具体的实现。
正如其他人所指出的,命名空间有助于管理具有相同名称的类。但是,如果出于某种原因,您需要MyCode::Point
直接使用TheirCode::Point
,则可以始终实施相应的运算符以进行每种可能的转换。但是,这并不是特别明智,因为随着数据类型的变体数量的增加,您必须为所有现有数据类型添加转换支持。
答案 2 :(得分:0)
如果我正确理解您的问题,您希望修改已存在于第三方库中的类,以满足您的需求。在这种情况下,库中的类由程序中定义的类继承。它就像从库中包装类来形成你需要的类。
库的目的是利用现有代码。通常最好使用库中的函数,然后创建自己的函数。是的,使用库确实会产生依赖性。但是,这就是软件的制作方式。库中的类通常会保持模块化,松散耦合,高内聚性。因此,他们只提供您所需要的,而不仅仅是。但是,您始终可以扩展这些类以添加特定于项目的功能。