Przeciążanie operatorów a błędy linkera

0

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;
}

2

Próbowałeś usunąć na próbę inline z headera przed operatorem +?

1

Nie możesz mieszać w ten sposób managed code z unmanaged. Przeczytaj to: http://blogs.msdn.com/b/branbray/archive/2005/07/20/441099.aspx
Btw, dlaczego akurat C++/CLI, a nie console application?

0

szweszwe działa, dzięki :) Nie spodziewałam się, że to będzie taki drobny błąd :)

1 użytkowników online, w tym zalogowanych: 0, gości: 1