Перегрузка оператор С++

247
26 ноября 2016, 18:56

Такой вопрос. Я перегружаю операторы для работы с вектором, который состоит из трек точек. Есть несколько задач:

  • Найти скалярное произведения векторов; (возвращает double)
  • Найти векторное произведения векторов; (возвращает вектор)

И получается такая проблема, что компилятор не знает какой из двух методов вызвать (хотя они отличаются возвращающимися параметрами). И как все это решить?

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 функции я знаю

Answer 1

Компилятор в общем случае не может определить, какую вызывать перегруженную функцию только по возвращаемому значению. Например, рассмотрите следующий фрагмент кода

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 * за исключением типа возвращаемого значения.

Answer 2

Понятие сигнатуры функции не включает возвращаемый тип, поэтому использовать перегрузку для одинаковых типов параметров, но разных возвращаемых типов в C++ нельзя.

Увы, решайте проблему иначе...

P.S. Недаром они даже в математике обозначаются по-разному :)

Answer 3

Тут можно постараться и сделать, например, такое (но это не означает, что так делать надо):

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;
}
READ ALSO
Ошибки SIGABRT и с sysmalloc

Ошибки SIGABRT и с sysmalloc

Пишу программу по двоичным деревьям

268
curl русские символы в url

curl русские символы в url

каким образом можно открыть курлом сайт с русскими символами в url?

404