Такой вопрос. Я перегружаю операторы для работы с вектором, который состоит из трек точек. Есть несколько задач:
И получается такая проблема, что компилятор не знает какой из двух методов вызвать (хотя они отличаются возвращающимися параметрами). И как все это решить?
using namespace std;
class Vec3D
{
private:
double x, y, z;
public:
Vec3D(double xx = 0, double yy = 0, double zz =0);
Vec3D operator+ (const Vec3D & V);
// double operator* (const Vec3D & V); // проблема тут
friend ostream& operator<< (ostream& cout, Vec3D & V);
friend Vec3D operator* (const double c, const Vec3D & V);
friend Vec3D operator* (const Vec3D & V1,const Vec3D & V2); // и тут
};
P.S. То что нужно реализовать семеричные\бинарные операции через friend функции я знаю
Компилятор в общем случае не может определить, какую вызывать перегруженную функцию только по возвращаемому значению. Например, рассмотрите следующий фрагмент кода
void f() {}
int f() { return 0; }
f();
Как определить, какая функция из двух вызывается?
Поэтому функции не перегружаются по возвращаемому значению.
Перегрузите этот оператор следующим образом, как показано в демонстрационной программе ниже.
#include <iostream>
class Vec3D
{
private:
double x, y, z;
public:
Vec3D( double x = 0, double y = 0, double z =0) : x( x ), y( y ), z( z )
{
}
friend std::ostream & operator <<( std::ostream &os, const Vec3D &v );
friend Vec3D operator *( const Vec3D &V, double d );
friend Vec3D operator *( double d, const Vec3D &v );
friend Vec3D operator *( const Vec3D &V1, const Vec3D &V2 ); // и тут
};
std::ostream & operator <<( std::ostream &os, const Vec3D &v )
{
return os << "( " << v.x << ", " << v.y << ", " << v.z << " )";
}
Vec3D operator *( const Vec3D &v, double d )
{
return Vec3D( d * v.x, d * v.y, d * v.z );
}
Vec3D operator *( double d, const Vec3D &v )
{
return v * d;
}
Vec3D operator *( const Vec3D &v1, const Vec3D &v2 )
{
return Vec3D( v1.x * v2.x, v1.y * v2.y, v1.z * v2.z );
}
int main()
{
Vec3D v1( 1, 2, 3 );
Vec3D v2( 1, 2, 3 );
std::cout << ( 2 * v1 ) * ( v2 * 3 ) << std::endl;
return 0;
}
Ее вывод на консоль
( 6, 24, 54 )
Нельзя перегрузить оператор по возвращаемому типу. Но вы могли бы взять еще один оператор, как, например, operator ^
, чтобы использовать его для одного из видов произведения векторов.
В итоге у вас может получиться два оператора
operator *
и
operator ^
Объявление перегруженного оператора operator ^
может выглядеть аналогично объявлению оператора operator *
за исключением типа возвращаемого значения.
Понятие сигнатуры функции не включает возвращаемый тип, поэтому использовать перегрузку для одинаковых типов параметров, но разных возвращаемых типов в C++ нельзя.
Увы, решайте проблему иначе...
P.S. Недаром они даже в математике обозначаются по-разному :)
Тут можно постараться и сделать, например, такое (но это не означает, что так делать надо):
http://ideone.com/8wAlaK
#include <cstdio>
struct v3d
{
double x, y, z;
};
struct v3d_mr // multiplication result
{
double scalar;
v3d vector;
operator double () { return this->scalar; }
operator v3d () { return this->vector; }
};
v3d_mr operator * (const v3d &a, const v3d &b)
{
return
{
a.x*b.x + a.y*b.y + a.z*b.z,
{ a.y*b.z - a.z*b.y, a.z*b.x - a.x*b.z, a.x*b.y - b.x*a.y }
};
}
int main()
{
v3d a = {1, 2, 3}, b = {4, 5, 6};
double s = a * b;
v3d v = a * b;
printf("%lf\n", s);
printf("%lf %lf %lf\n", v.x, v.y, v.z);
return 0;
}
Перевод документов на английский язык: Важность и ключевые аспекты
Какие существуют виды рекламных бордов и как выбрать подходящий?