Hej :) Potrzebuję pomocy w pozbyciu się dziwnych błędów. Jestem początkująca także proszę o używanie w miarę prostego języka :).
Napisałam klasę Vector3D, która ma implementować matematyczny wektor [x,y,z] z przeciążonymi operatorami i innymi bajerami typu iloczyn skalarny i wektorowy. W funkcji main próbuję dodać dwa wektory do siebie i wyskakują mi takie błędy:
Error 1 error LNK2028: unresolved token (0A000345) "public: class Vector3D __thiscall Vector3D::operator+(class Vector3D const &)" (??HVector3D@@$$FQAE?AV0@ABV0@@Z) referenced in function "int __clrcall main(cli::array<class System::String ^ >^)" (?main@@$$HYMHP$01AP$AAVString@System@@@Z) D:\II stopień\praca magisterska\raytracer\Raytracer back\OpenGL_on_a_Windows_Form\Main.obj
Error 2 error LNK2019: unresolved external symbol "public: class Vector3D __thiscall Vector3D::operator+(class Vector3D const &)" (??HVector3D@@$$FQAE?AV0@ABV0@@Z) referenced in function "int __clrcall main(cli::array<class System::String ^ >^)" (?main@@$$HYMHP$01AP$AAVString@System@@@Z) D:\II stopień\praca magisterska\raytracer\Raytracer back\OpenGL_on_a_Windows_Form\Main.obj
Error 3 error LNK1120: 2 unresolved externals D:\II stopień\praca magisterska\raytracer\Raytracer back\Debug\Raytracer.exe 1
Pracuję w Visual Studio 2010 na projekcie Windows Forms. Wywoływanie funkcji z klasy Vector3D działa ok, konstruktory działają zarówno gdy są w pliku .h jak i w .cpp. Problemy są tylko z operatorami (poza operatorem <<<). Gdzie może leżeć błąd?
Plik Vector3D.h
#pragma once
//#ifndef __VECTOR3D__
//#define __VECTOR3D__
#include <ostream>
#include <math.h>
#include <string>
using std::ostream;
class Vector3D
{
public:
//wspolrzedne
float x;
float y;
float z;
//konstruktory
Vector3D(float _x) {
x = _x;
y = _x;
z = _x;
}
Vector3D() {
x = 0;
y = 0;
z = 0;
}
Vector3D(float _x, float _y, float _z) {
x = _x;
y = _y;
x = _z;
}
Vector3D(const Vector3D& vec) {
x = vec.x;
y = vec.y;
z = vec.z;
}
//operator []
float& operator[] (int index) {
if (index == 0)
return x;
else if (index == 1)
return y;
else if (index == 2)
return z;
}
const float& operator[] (int index) const {
if (index == 0)
return x;
else if (index == 1)
return y;
else if (index == 2)
return z;
}
//rzutowanie wektora na wybrana plaszczyzne
void castVec(float *px, float *py, int plane) const;
//normalizacja wektora
Vector3D normalize();
// dlugosc wektora
inline float magnitude();
//operatory przypisania
inline Vector3D& operator+= (const Vector3D& vec);
inline Vector3D& operator-= (const Vector3D& vec);
inline Vector3D& operator*= (const Vector3D& vec);
inline Vector3D& operator*= (float number);
inline Vector3D& operator/= (float number);
//operatory binarne
inline Vector3D operator+ (const Vector3D& vec);
inline Vector3D operator- (const Vector3D& vec);
inline Vector3D operator* (const Vector3D& vec); //domyślnie mnożenie tablicowe (nie jak macież)
inline Vector3D operator/ (const Vector3D& vec);
inline Vector3D operator* (float number);
inline Vector3D operator/ (float number);
friend inline Vector3D operator* (float number, const Vector3D& vec); //zaprzyjaźniony bo na rzecz innego obiektu
inline int operator< (const Vector3D& vec);
inline int operator== (const Vector3D& vec);
//dzialania na wektorach
static inline Vector3D crossProduct (const Vector3D & vecA, const Vector3D & vecB); //iloczyn wektorowy
static inline float dotProduct (const Vector3D& vecA, const Vector3D& vecB); //iloczyn skalarny
static inline void minimal(Vector3D& _min, const Vector3D& other);
static inline void maximal(Vector3D& _max, const Vector3D& other);
//ostream
friend ostream & operator<< (ostream & s, const Vector3D & vec);
//unarne
Vector3D operator+ () const;
Vector3D operator- () const;
};
//#endif
Plik Vector3D.cpp
#include "StdAfx.h"
#include "Vector3D.h"
using namespace std;
//rzutowanie wektora na płaszczyzne: 0 - YZ, 1 - XZ, 2 - XY
void Vector3D::castVec(float *px, float *py, int plane) const {
switch(plane) {
case 0:
*px = y;
*py = z;
break;
case 1:
*px = x;
*py = z;
break;
case 2:
*px = x;
*py = y;
break;
}
}
//normalizacja
Vector3D Vector3D::normalize() {
float m = magnitude();
return Vector3D(x/m, y/m, z/m);
}
//dlugosc wektora
float Vector3D::magnitude() {
return sqrt(x*x + y*y + z*z);
}
//operatory przypisania
Vector3D & Vector3D::operator+= (const Vector3D& vec) {
x+=vec.x;
y+=vec.y;
z+=vec.z;
return *this;
}
Vector3D & Vector3D::operator-= (const Vector3D& vec) {
x-=vec.x;
y-=vec.y;
z-=vec.z;
return *this;
}
Vector3D & Vector3D::operator*= (const Vector3D& vec) {
x*=vec.x;
y*=vec.y;
z*=vec.z;
return *this;
}
Vector3D & Vector3D::operator*= (float number) {
x*=number;
y*=number;
z*=number;
return *this;
}
inline Vector3D& Vector3D::operator/= (float number) {
x/=number;
y/=number;
z/=number;
return *this;
}
//operatory binarne
Vector3D Vector3D::operator+ (const Vector3D& vec) {
return Vector3D(x+vec.x, y+vec.y, z+vec.z);
}
Vector3D Vector3D::operator- (const Vector3D& vec) {
return Vector3D(x-vec.x, y-vec.y, z-vec.z);
}
Vector3D Vector3D::operator* (const Vector3D& vec) { //domyślnie mnożenie tablicowe
return Vector3D(x*vec.x, y*vec.y, z*vec.z);
}
Vector3D Vector3D::operator/ (const Vector3D& vec) {
return Vector3D(x/vec.x, y/vec.y, z/vec.z);
}
Vector3D Vector3D::operator* (float number) {
return Vector3D(x*number, y*number, z*number);
}
Vector3D Vector3D::operator/ (float number) {
return Vector3D(x/number, y/number, z/number);
}
Vector3D operator* (float number, const Vector3D& vec) { //odwrotne mnożenie (na rzecz innego obiektu)
return Vector3D(vec.x*number, vec.y*number, vec.z*number);
}
int Vector3D::operator< (const Vector3D& vec) {
return x<vec.x && y<vec.y && z<vec.z;
}
int Vector3D::operator== (const Vector3D& vec) {
return (x == vec.x) && (y == vec.y) && (z == vec.z);
}
Vector3D Vector3D::operator+ () const {
return *this;
}
Vector3D Vector3D::operator- () const {
return Vector3D(-x,-y,-z);
}
//iloczyn skalarny
float Vector3D::dotProduct(const Vector3D & vecA, const Vector3D & vecB) {
return vecA.x*vecB.x + vecA.y*vecB.y + vecA.z*vecB.z;
}
//iloczyn wektorowy
Vector3D Vector3D::crossProduct (const Vector3D & vecA, const Vector3D & vecB) {
return Vector3D(vecA.y*vecB.z - vecA.z*vecB.y, vecA.z*vecB.x - vecA.x*vecB.z, vecA.x*vecB.y - vecA.y*vecB.x);
}
//porownuje wspolrzedne wektorow i wstawia do zwraca wektora te mniejsze
void Vector3D::minimal(Vector3D& _min, const Vector3D& other) {
if(other.x < _min.x)
_min.x = other.x;
if(other.y < _min.y)
_min.y = other.y;
if(other.z < _min.z)
_min.z = other.z;
}
//porownuje wspolrzedne wektorow i wstawia do zwraca wektora te wieksze
void Vector3D::maximal(Vector3D& _max, const Vector3D& other) {
if(other.x > _max.x)
_max.x = other.x;
if(other.y > _max.y)
_max.y = other.y;
if(other.z > _max.z)
_max.z = other.z;
}
//ostream
ostream & operator<< (ostream & s, const Vector3D & vec) {
return s << "(" << vec.x << ", " << vec.y << ", " <<vec.z << ")";
}
Main.cpp
#include "stdafx.h"
#include "Form1.h"
#include "Vector3D.h"
using namespace Raytracer;
[STAThreadAttribute]
int main(array<System::String ^> ^args)
{
Application::EnableVisualStyles();
Application::SetCompatibleTextRenderingDefault(false);
// Uruchomienie okna głównego
Application::Run(gcnew Form1());
Vector3D vec1(1);
Vector3D vec2(2);
vec1+vec2;
return 0;
}