2016-08-24 3 views
1

Я пишу простой класс C++ под названием Vector2f. У меня есть файл класса Vector2f.cpp и заголовочный файл с именем Vector2f.h.Ошибка перегрузки функции при перегрузке cmath-функции C++

Моего Vector2f класс имеет функцию с именем abs, который возвращает новый Vector2f с абсолютным значением каждого из компонентов исходного Vector2f. Я использую библиотеку cmath. Однако, когда я пытаюсь использовать функцию cmath abs, он думает, что я имею в виду некоторую неопределенную функцию Vector2f::abs(float), а не функцию cmath abs. Почему здесь существует конфликт имен? Если не C++ быть в состоянии решить, что функция называется abs, которая принимает поплавка определяется только в CMATH, а не в Vector2f.h

Вот мой код:

Мой заголовочный файл:

//Vector2f.h 

#ifndef VECTOR2F_H 
#define VECTOR2F_H 

class Vector2f 
{ 
private: 
    float x; 
    float y; 

public: 
    Vector2f(float x, float y); 
    float length(); 
    float dot(Vector2f r); 
    Vector2f normalized(); 
    Vector2f rot(float angle); 
    Vector2f add(Vector2f r); 
    Vector2f add(float r); 
    Vector2f sub(Vector2f r); 
    Vector2f sub(float r); 
    Vector2f mul(Vector2f r); 
    Vector2f mul(float r); 
    Vector2f div(Vector2f r); 
    Vector2f div(float r); 
    Vector2f abs(); 
    float getX(); 
    float getY(); 

}; 

#endif // VECTOR2F_H 

Мой файл класса:

//Vector2f.cpp 

#ifndef M_PI 
#define M_PI 3.14159265358979323846264338327950288 
#endif // M_PI 
#include "Vector2f.h" 
#include <cmath> 

Vector2f::Vector2f(float x, float y) 
{ 
    this -> x = x; 
    this -> y = y; 
} 
float Vector2f::length() 
{ 
    return (float)sqrt(x * x + y * y); 
} 

float Vector2f::dot(Vector2f r) 
{ 
    return x * r.getX() + y * r.getY(); 
} 

Vector2f Vector2f::normalized() 
{ 
    float length = Vector2f::length(); 

    float xnormal = x/length; 
    float ynormal = y/length; 

    return Vector2f(xnormal, ynormal); 
} 

Vector2f Vector2f::rot(float angle) 
{ 
    double rad = angle * M_PI/180.0; 
    double c = cos(rad); 
    double s = sin(rad); 

    return Vector2f((float)(x * c - y * s), (float)(x * s + y * c)); 
} 

Vector2f Vector2f::add(Vector2f r) 
{ 
    return Vector2f(x + r.getX(), y + r.getY()); 
} 

Vector2f Vector2f::add(float r) 
{ 
    return Vector2f(x + r, y + r); 
} 

Vector2f Vector2f::sub(Vector2f r) 
{ 
    return Vector2f(x - r.getX(), y - r.getY()); 
} 

Vector2f Vector2f::sub(float r) 
{ 
    return Vector2f(x - r, y - r); 
} 
Vector2f Vector2f::mul(Vector2f r) 
{ 
    return Vector2f(x * r.getX(), y * r.getY()); 
} 

Vector2f Vector2f::mul(float r) 
{ 
    return Vector2f(x * r, y * r); 
} 
Vector2f Vector2f::div(Vector2f r) 
{ 
    return Vector2f(x/r.getX(), y/r.getY()); 
} 

Vector2f Vector2f::div(float r) 
{ 
    return Vector2f(x/r, y/r); 
} 
Vector2f Vector2f::abs() 
{ 
    //I get the error, "error: no matching function for call to 'Vector2f::abs(float&)'", here 
    //when trying to call abs(x) and abs(y) 
    float xabs = abs(x); 
    float yabs = abs(y); 
    return Vector2f(xabs, yabs); 
} 
float Vector2f::getX() 
{ 
    return x; 
} 
float Vector2f::getY() 
{ 
    return y; 
} 

Мой главный файл:

//main.cpp 

#include <iostream> 
#include "Vector2f.h" 

using namespace std; 

int main() 
{ 
    Vector2f a(1.0f,2.0f); 

    cout<<a.getX()<<','<<a.getY()<<endl; 

    cout<<a.abs()<<endl; 

    return 0; 
} 

Любая помощь будет оценена по достоинству.

Edit:

Сообщение об ошибке:

error: no matching function for call to 'Vector2f::abs(float&)' 

at line 80: 

float xabs = abs(x); 

error: no matching function for call to 'Vector2f::abs(float&)' 

at line 81: 

float yabs = abs(y); 
+0

Какое сообщение об ошибке? – songyuanyao

+1

Я вижу, что вы объявили дополнительную функцию 'float abs (float);' в вашем классе 'Vector', но вы ее не реализовали. – Neozaru

+0

... но вы объявили метод 'float abs (float)' в вашем классе 'Vector2f', просто не реализовали его. Конечно, он попытается использовать этот. Удалите объявление. –

ответ

3

Компилятор делает unqualified lookup из abs. То, что происходит тогда, зависит от того, что вы включаете, и если есть использование объявления (и, что интересно, в компиляторе). Все в cmath определено в пространстве имен std, поэтому вам необходимо квалифицировать свой вызов с помощью std::.

Vector2f Vector2f::abs() 
{ 
    //I get the error, "undefined reference to `Vector2f::abs(float)'", here 
    //when trying to call abs(x) and abs(y) 
    float xabs = std::abs(x); 
    float yabs = std::abs(y); 
    return Vector2f(xabs, yabs); 
} 

Если у вас есть using std::abs или using namespace std где-то до Vector2d::abs, вы можете претендовать только ::abs. Compilers are allowed to declare C functions such as abs in the global namespace in addition to namespace std, поэтому в зависимости от компилятора с использованием ::abs может работать или нет, не используя декларации вообще. Clang 3.8 принимает код, gcc - нет.

PS: Я ожидал бы функции Vector2f::abs для вычисления векторной нормы, а не вектора с абсолютными значениями исходных компонентов. Но тогда я не математик.

+0

Да, я только что редактировал мой вопрос с правильной реализацией. Я все равно получаю другую ошибку. –

+0

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

+0

@OrrenRavid Я все еще вижу 'float xabs = abs (x);' в вопросе. В общем, было бы лучше разместить минимальные примеры с полным сообщением об ошибке. – Jens