我可以使用C ++中的任何方法,例如重载或模板,这样我可以将类实例作为参数传递给cmath函数吗?例如,如果我有一个名为“Point”的类(如下所示),是否有任何方法可以执行操作std::abs(Point(-4, -9))
并让它返回Point(4, 9)
?< / p>
#include <iostream>
#include <cmath>
class Point{
private:
double x, y;
public:
Point(double x, double y) {
this->x = x;
this->y = y;
}
// Approach 1 that I would like to avoid
static Point abs1(const Point &p1) {
return Point(std::abs(p1.x), std::abs(p1.y));
}
// Approach 2 that I would like to avoid
Point abs2(void) {
return Point(std::abs(x), std::abs(y));
}
};
int main()
{
Point pt1(-4.0, -9.0), pt2;
pt2 = std::abs(pt1) // <-- What I would like to be able to do
pt2 = Point::abs1(point_d); // <-- Function call 1 that I would like to avoid
pt2 = point_d.abs2(); // <-- Function call 2 that I would like to avoid
return 0;
}
或者我是否仅限于使用需要拨打Point::abs(Point(-4, -9))
或Point(-4, -9).abs()
的基于类的方法?所以简而言之,我可以在任何方面扩充cmath函数来接受类实例吗?
我浏览了一下,找不到有关该主题的任何信息,但我对C ++很陌生。所以,我会感谢有关如何做到这一点的任何信息,是否可以做到,以及这样的行动是否是不明智的,如果是,为什么?
提前致谢。
答案 0 :(得分:2)
查看this参考页:
为了计算绝对值,在cmath中你只有一堆对基本类型进行操作的重载:
int abs(int j);
long int abs(long int j);
long long int abs(long long int j);
float abs(float j);
double abs(double j);
long double abs(long double j);
由于这些函数不是模板化的,因此无法向它们传递Point类并返回Point的另一个实例。它们只能接收基本类型,并返回相同的类型。
如果你的Point类可以转换为其中一种原始类型,那么这样的东西(仅在语法方面类似)才会发生。例如。在下面的代码片段中,我定义了类A,它可以隐式转换为int和int,因此当我用一个A实例调用abs
时,它会自动转换为int,传递给{{1的适当重载最后将结果转换回A。
abs
但这就是你可以用这个技巧走多远,我认为这并不能涵盖你想要的东西。我认为在你的情况下最好的方法是创建一些实用功能,做你想要的。我宁愿选择一个免费的函数,而不是一个静态成员,不要用不必要的实用方法乱丢这个类,就像这样的东西
#include <cmath>
#include <iostream>
class A
{
public:
A(int x_) // implicit conversion from int
: x(x_)
{}
operator int()
{
return x; // implicit conversion to int
}
private:
int x;
};
int Foo(int x)
{
return x * 2;
}
int main()
{
A a1(-2);
A a2 = Foo(a1);
A a3 = std::abs(a1);
std::cout << "a2: " << a2 << "\n";
std::cout << "a3: " << a3 << "\n";
getchar();
}
答案 1 :(得分:1)
您展示的两种方法是有效的方法。没有办法直接在你的Point类上使用std :: abs。
另一种方法是将静态abs1函数转换为自由abs函数。如果它的声明在头文件中,它实质上会重载std :: abs函数。为了将其作为自由函数实现,您需要实现成员函数来获取x和y,或者让您的自由函数成为Point类的朋友。
答案 2 :(得分:1)
你会这样做。
#include <iostream>
#include <cmath>
class Point{
double x, y;
public:
Point(double x, double y)
: x(x), y(y)
{
}
friend Point abs(const Point &p1) {
return Point(std::abs(p1.x), std::abs(p1.y));
}
};
int main()
{
using std::abs;
Point pt1(-4.0, -9.0);
double x = 5.5;
// this will work even if Point is in its own namespace
// because of ADL
Point pt2 = abs(pt1);
// this works because for this function, we have pulled
// std::abs into the global namespace
double y = abs(x);
return 0;
}