Szablony w C++ problem z działaniem

0

Cześć, mam problem ze skompilowaniem programu w Microsoft Visual Studio 2012, a mianowicie podczas kompilacji pojawiaja się błędy:

1>------ Build started: Project: Program1, Configuration: Debug Win32 ------
1>  my_coord.cpp
1>my_interf.obj : error LNK2019: unresolved external symbol "class std::basic_istream<char,struct std::char_traits<char> > & __cdecl operator>>(class std::basic_istream<char,struct std::char_traits<char> > &,class my_coord &)" (??5@YAAAV?$basic_istream@DU?$char_traits@D@std@@@std@@AAV01@AAVmy_coord@@@Z) referenced in function "public: void __thiscall my_interf::find(void)" (?find@my_interf@@QAEXXZ)
1>my_interf.obj : error LNK2019: unresolved external symbol "class std::basic_ostream<char,struct std::char_traits<char> > & __cdecl operator<<(class std::basic_ostream<char,struct std::char_traits<char> > &,class my_coord &)" (??6@YAAAV?$basic_ostream@DU?$char_traits@D@std@@@std@@AAV01@AAVmy_coord@@@Z) referenced in function "public: void __thiscall my_interf::find(void)" (?find@my_interf@@QAEXXZ)
1>my_interf.obj : error LNK2019: unresolved external symbol "public: __thiscall my_vect<class my_coord>::~my_vect<class my_coord>(void)" (??1?$my_vect@Vmy_coord@@@@QAE@XZ) referenced in function __unwindfunclet$??0my_interf@@QAE@I@Z$0
1>Program1.obj : error LNK2001: unresolved external symbol "public: __thiscall my_vect<class my_coord>::~my_vect<class my_coord>(void)" (??1?$my_vect@Vmy_coord@@@@QAE@XZ)
1>my_interf.obj : error LNK2019: unresolved external symbol "public: void __thiscall my_vect<class my_coord>::init(unsigned int)" (?init@?$my_vect@Vmy_coord@@@@QAEXI@Z) referenced in function "public: __thiscall my_interf::my_interf(unsigned int)" (??0my_interf@@QAE@I@Z)
1>my_interf.obj : error LNK2019: unresolved external symbol "public: class my_coord * __thiscall my_vect<class my_coord>::get_begin(void)" (?get_begin@?$my_vect@Vmy_coord@@@@QAEPAVmy_coord@@XZ) referenced in function "public: void __thiscall my_interf::find(void)" (?find@my_interf@@QAEXXZ)
1>my_interf.obj : error LNK2019: unresolved external symbol "public: class my_coord * __thiscall my_vect<class my_coord>::get_end(void)" (?get_end@?$my_vect@Vmy_coord@@@@QAEPAVmy_coord@@XZ) referenced in function "public: void __thiscall my_interf::find(void)" (?find@my_interf@@QAEXXZ)
1>my_interf.obj : error LNK2019: unresolved external symbol "public: void __thiscall my_vect<class my_coord>::disp(void)" (?disp@?$my_vect@Vmy_coord@@@@QAEXXZ) referenced in function "public: void __thiscall my_interf::disp(void)" (?disp@my_interf@@QAEXXZ)
1>my_interf.obj : error LNK2019: unresolved external symbol "public: void __thiscall my_vect<class my_coord>::push(class my_coord const &)" (?push@?$my_vect@Vmy_coord@@@@QAEXABVmy_coord@@@Z) referenced in function "public: void __thiscall my_interf::push(void)" (?push@my_interf@@QAEXXZ)
1>my_interf.obj : error LNK2019: unresolved external symbol "public: class my_coord * __thiscall my_vect<class my_coord>::pop(void)" (?pop@?$my_vect@Vmy_coord@@@@QAEPAVmy_coord@@XZ) referenced in function "public: void __thiscall my_interf::pop(void)" (?pop@my_interf@@QAEXXZ)
1>Program1.obj : error LNK2019: unresolved external symbol "public: void __thiscall my_interf::finish(void)" (?finish@my_interf@@QAEXXZ) referenced in function _wmain
1>Program1.obj : error LNK2019: unresolved external symbol "public: void __thiscall my_interf::defaul(void)" (?defaul@my_interf@@QAEXXZ) referenced in function _wmain
1>C:\Users\Wojtek\Documents\Ćwiczenia\Ćwiczenie 1\Program1\Debug\Program1.exe : fatal error LNK1120: 11 unresolved externals
========== Build: 0 succeeded, 1 failed, 0 up-to-date, 0 skipped ==========

 

Dodam, że do tej pory nie spotkałem się z tego typu błędami, dlatego chicałbym Was prosić o pomoc.

Poniżej zamieszczam wszystkie pliki, jakie utworzyłem do projektu - jest ich sporo, ale w takich plikach miały być poszczegolne czeseci zadania.

my_coord.h

 
#include "my_mess.h"
#include <iostream>
using namespace std;

class my_coord
{
	double *pcoord;  //pcoord[0] -; pcoord[1] - y
	my_mess msg;
public:
	my_coord() { alloc(); pcoord[0] = pcoord[1] = 0; }
	my_coord(double x, double y);
	~my_coord();

	bool operator==(const my_coord &ob);
	bool operator !=(const my_coord &ob);
private:
	void alloc();

	friend istream & operator>>(istream & wejscie, my_coord & obj);
	friend ostream & operator<<(ostream & wyjscie, my_coord & obj);
};

my_coord.cpp

#include "stdafx.h"
#include "my_coord.h"
#include <iostream>
using namespace std;

my_coord::my_coord(double x, double y)
{
	alloc();

	pcoord[0]=x;
	pcoord[1]=y;
}

my_coord::~my_coord()
{
	if(pcoord)
		delete [] pcoord;
}

bool my_coord::operator==(const my_coord &ob)
{
	if(pcoord[0] != ob.pcoord[0])
		return false;
	else if(pcoord[1]!=ob.pcoord[1])
		return false;
	
	return true;
}

bool my_coord::operator!=(const my_coord &ob)
{
	if(pcoord[0]==ob.pcoord[0])
		return false;
	else if(pcoord[1]==ob.pcoord[1])
		return false;
	
	return true;
}

void my_coord::alloc()
{
	pcoord=0;
	
	try
	{
		pcoord= new double [2];
	}

	catch(bad_alloc)
	{
		msg.mess(my_mess::ERR_ALLOC_MEM);
	}
}

 

my_interf.h

 

#define MAX_INTERF_CHAR 512

#include "my_vect.h"
#include "my_coord.h"


class my_interf
{
public:
	enum MY_INTERF
	{
		MY_INTERF_PUSH,
		MY_INTERF_POP,
		MY_INTERF_DISP,
		MY_INTERF_FIND,
		MY_INTERF_FINISH,
		MY_INTERF_TOT	
	};
private:
	my_vect<my_coord> vect;
	char str_interf[MY_INTERF_TOT][MAX_INTERF_CHAR];  //komunikaty, wyświetlane na monitorze
	my_mess msg;
public:
	bool run;

	my_interf();
	my_interf(size_t dim);
	void menu();
	void push();
	void pop();
	void disp();
	void find();
	void finish();
	void defaul();
};


my_interf.cpp

 

///////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////my_interf.cpp

#include "stdafx.h"
#include "my_interf.h"
//#include <iostream>
//using namespace std;

my_interf::my_interf(size_t dim)
{
	sprintf_s(str_interf[MY_INTERF_PUSH], MAX_INTERF_CHAR*sizeof(char), "%d - push", MY_INTERF_PUSH);
	sprintf_s(str_interf[MY_INTERF_POP], MAX_INTERF_CHAR*sizeof(char), "%d - pop", MY_INTERF_POP);
	sprintf_s(str_interf[MY_INTERF_DISP], MAX_INTERF_CHAR*sizeof(char), "%d - disp", MY_INTERF_DISP);
	sprintf_s(str_interf[MY_INTERF_FIND], MAX_INTERF_CHAR*sizeof(char), "%d - find", MY_INTERF_FIND);
	sprintf_s(str_interf[MY_INTERF_FINISH], MAX_INTERF_CHAR*sizeof(char), "%d - finish", MY_INTERF_FINISH);
	vect.init(dim);
	run = true;
}

void my_interf::menu()
{
	int i;
	for(i=0; i<MY_INTERF_TOT; i++)
	{
		cout << str_interf[i] << endl;
	}
}

void my_interf::push()
{
	my_coord ob(0,0);
	cin >> ob;
	vect.push(ob);
}

void my_interf::pop()
{
	my_coord *ptr = NULL;
	ptr = vect.pop();
	if(ptr)
	{
		cout << *ptr;
	}
	else
	{
		msg.mess(my_mess::WARN_ARR_EMPT);
	}
}

void my_interf::disp()
{
	vect.disp();
}

void my_interf::find()
{
	my_coord ob(0, 0);
	my_coord *ptr = NULL;
	cout << "input x, y - object for search\n";
	cin >> ob;
	ptr = vect.get_begin();
	size_t dist;
	while(ptr)
	{
		ptr = Find(ptr, vect.get_end(), ob);
		if(ptr)
		{
			dist = ptr-vect.get_begin();
			cout << "it = " << dist << " " << *ptr;
			ptr++;
		}
		else
			cout << "search end\n";
	}
}

my_mess.h


///////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////my_mess.h

#ifndef INCLUDE_MY_HEADER_my_mess_h
#define INCLUDE_MY_HEADER_my_mess_h
#include <iostream>
using namespace std;
class my_mess
{
public:
	enum MY_MESSAGE
	{
		ERR_ALLOC_MEM,     //błąd alokacji pamięci
		WARN_ARR_FULL,     //tablica jest wypelniona (last > ndim)
		WARN_ARR_EMPT,     //tablica jest pusta (last = 0)
		WARN_ARR_UNKN,     //niepoprawny kod działania (interfejs)
		TOT_NUMB                 //ogólna ilość komunikatów
	};

	static char *strtab[TOT_NUMB];  //tablica tekstowa komunikatów

public:
	void mess(enum MY_MESSAGE ms);    //Przy wywołani tej funkcji na ekran //pozostaje wyprowadzony komunikat. Jeśli to błąd, obliczenia trzeba //skończyć, jeśli nie – kontynuować. ms – składowa enumeration, która podaje //numer komunikatu
};


#endif
 

my_mess.cpp

 

///////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////my_mess.cpp

#include "stdafx.h"
#include "my_mess.h"
//#include <iostream>
//using namespace std;

char *my_mess::strtab[] =
{
	"E  memory alloc error",          //ERR_ALLOC_MEM
	"W  array is full",               //WARN_ARR_FULL
	"W  array is empty",              //WARN_ARR_EMPT
	"W  niepoprawny kod operacji"     //WARN_ARR_UNKN
};

void my_mess::mess(enum MY_MESSAGE ms)
{
	if(strtab[ms][0] == 'E')
	{
		cout << "ERROR: " << &strtab[ms][1] << endl;
		system("pause");
		exit(1);
	}
	else if(strtab[ms][0] == 'W')
	{
		cout << "WARNING: " << &strtab[ms][1] << endl;
	}
}

my_vect.h

 

///////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////my_vect.h

#ifndef INCLUDE_MY_HEADER_my_vect_h
#define INCLUDE_MY_HEADER_my_vect_h

#include "my_mess.h"
#include <fstream>

template <class T>
class my_vect
{
	T *dat;        //wskaznik do danych typu ogolnego
	size_t ndim;   //rozmiar tablicy, na ktory pozostala zaalokowana
	size_t last;   //wskazuje na pierwsza pusta pozycje w tablice
	my_mess msg;

public:
	my_vect(size_t dm); //konstruktor - alokuje pamiec dla tablicy typu T 
						//na dm elementow
	my_vect() { dat = NULL; ndim = last = 0; }
	~my_vect();
	void init(size_t dm);	//alokuje pamiec o dm elementow, jesli dat = NULL
	T *get_begin();			//zwraca wskaźnik do początku tablicy dat
	T *get_end();			//zwraca wskaźnik do dat[last]
	void disp();			//wyswietla stan tablicy
	void push(const T &ob); //dodaje element typu T do pierwszej wolnej 
							//pozycji w tablice
	T *pop();               //zwraca wskaznik do ostatniego elementu tablicy 
							//i usuwa jego, lub NULL (tablica pusta)
	T & operator [] (const size_t ind); //0 <= ind < last
	void remove(size_t ind); //usuwa element tablicy o indeksie ind, kompresuje tablicu
private:
	bool alloc();            //alocuje pamięć
};


template <class T, class K>
T *Find(const T *p_begin, const T *p_end, const K &key)
{
	if(p_begin==NULL)
	{
		cout<<"Podany wskaznik do tablicy jest pusty"<<endl;
		return NULL;
	}

	T *wsk=const_cast<T*>(p_begin);
	while(*wsk != *p_end)
	{
		if(*wsk==key)
			return wsk;
		++wsk;
	}

	return NULL;
}

#endif

my_vect.cpp


///////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////my_vect.cpp

#include "stdafx.h"
#include "my_vect.h"
#include <iostream>
using namespace std;

template <class T>
my_vect<T>::my_vect(size_t dm)
{
	dat=NULL;
	last=0;
	ndim=dm;
	alloc();
}

template <class T>
my_vect<T>::~my_vect()
{
	if(dat)
		delete [] dat;
}

template <class T>
void my_vect<T>::init(size_t dm)
{
	if(dat == NULL)
	{
		last=0;
		ndim=dm;
		alloc();
	}
}

template <class T>
T *my_vect<T>::get_begin()
{
	return dat;
}

template <class T>
T *my_vect<T>::get_end()
{
	return dat+last;
}

template <class T>
void my_vect<T>::disp()
{
	T *ptr=get_begin();

	for(;ptr != get_end(); ptr++)
		cout<<*ptr<<" ";
	cout<<endl;
}

template <class T>
void my_vect<T>::push(const T &ob)
{
	if(last>=ndim)
		if(!realloc())
		{
			msg.mess(my_mess::ERR_ALLOC_MEM);
		}

	if(dat)
	{
		dat[last]=ob;
		++last;
	}
}

template <class T>
T *my_vect<T>::pop()
{
	if(dat && last)
		return &dat[--last];
	else
		return NULL;
}

template <class T>
T & my_vect<T>::operator[](const size_t ind)
{
	if(dat && (ind>=0) && (ind<last))
		return dat[ind];
}

template <class T>
bool my_vect<T>::alloc()
{
	if(!dat)
	{
		try
		{
			dat= new T[ndim];
		}
		catch(bad_alloc)
		{
			msg.mess(my_mess::ERR_ALLOC_MEM);
		}
	}
	return true;
}


 

Program1.cpp


// LAB 7 - Program1.cpp : Defines the entry point for the console application.
//

#include "stdafx.h"
#include "my_interf.h"



int _tmain(int argc, _TCHAR* argv[])
{
	int op;  //operacje
	my_interf ifc(1000);
	
	while(ifc.run)
	{
		ifc.menu();
		cin >> op;
		switch(op)
		{
		case my_interf::MY_INTERF_PUSH: //push
			ifc.push();
			break;
		case my_interf::MY_INTERF_POP:
			ifc.pop();
			break;
		case my_interf::MY_INTERF_DISP:
			ifc.disp();
			break;
		case my_interf::MY_INTERF_FIND:
			ifc.find();
			break;
		case my_interf::MY_INTERF_FINISH:
			ifc.finish();
			break;
		default:
			ifc.defaul();
		};
	}	

	system("pause");	
	return 0;
}

 
0

A masz gdzieś te operatory zaimplementowane:

friend istream & operator>>(istream & wejscie, my_coord & obj);
friend ostream & operator<<(ostream & wyjscie, my_coord & obj);

Ogólnie szablony potrafią rzucać baardzo nieczytelnymi wyjątkami (zasadniczo ciężko opisać jak je czytać, najłatwiej szukać nazw znanych metod i myślisz co z nimi może być źle), a to że dałeś olbrzymią ilość kodu nie pomaga (nie ma jak uruchomić łatwo) ;].
Jeśli nie to to będziemy kombinować dalej.

0

Sorka coś mi się ucięło. Jest dodane to w pliku my_coord.h zaraz za klasą

istream & operator>>(istream & wejscie, my_coord &obj)
{
	cout<<"Podaj x: ";
	wejscie>>obj.pcoord[0];
	cout<<"Podaj y: ";
	wejscie>>obj.pcoord[1];

	return wejscie;
}

ostream & operator<<(ostream & wyjscie, my_coord & obj)
{
	wyjscie<<"x= "<<obj.pcoord[0]<<" y= "<<obj.pcoord[1]<<endl;

	return wyjscie;
}

 

lecz nadal jest to samo.

0

A powinny być w: my_coord.cpp

0

A dla czego metoda friend nie może być w my_coord.h? Czy może chodzi o uporządkowanie kodu - ze deklaruje w headerze a pozniej w Cpp mam ich metody?

Po przeniesieniu nadal występują błędy:

>------ Build started: Project: Program1, Configuration: Debug Win32 ------
1>  my_coord.cpp
1>my_interf.obj : error LNK2019: unresolved external symbol "public: __thiscall my_vect<class my_coord>::~my_vect<class my_coord>(void)" (??1?$my_vect@Vmy_coord@@@@QAE@XZ) referenced in function __unwindfunclet$??0my_interf@@QAE@I@Z$0
1>Program1.obj : error LNK2001: unresolved external symbol "public: __thiscall my_vect<class my_coord>::~my_vect<class my_coord>(void)" (??1?$my_vect@Vmy_coord@@@@QAE@XZ)
1>my_interf.obj : error LNK2019: unresolved external symbol "public: void __thiscall my_vect<class my_coord>::init(unsigned int)" (?init@?$my_vect@Vmy_coord@@@@QAEXI@Z) referenced in function "public: __thiscall my_interf::my_interf(unsigned int)" (??0my_interf@@QAE@I@Z)
1>my_interf.obj : error LNK2019: unresolved external symbol "public: class my_coord * __thiscall my_vect<class my_coord>::get_begin(void)" (?get_begin@?$my_vect@Vmy_coord@@@@QAEPAVmy_coord@@XZ) referenced in function "public: void __thiscall my_interf::find(void)" (?find@my_interf@@QAEXXZ)
1>my_interf.obj : error LNK2019: unresolved external symbol "public: class my_coord * __thiscall my_vect<class my_coord>::get_end(void)" (?get_end@?$my_vect@Vmy_coord@@@@QAEPAVmy_coord@@XZ) referenced in function "public: void __thiscall my_interf::find(void)" (?find@my_interf@@QAEXXZ)
1>my_interf.obj : error LNK2019: unresolved external symbol "public: void __thiscall my_vect<class my_coord>::disp(void)" (?disp@?$my_vect@Vmy_coord@@@@QAEXXZ) referenced in function "public: void __thiscall my_interf::disp(void)" (?disp@my_interf@@QAEXXZ)
1>my_interf.obj : error LNK2019: unresolved external symbol "public: void __thiscall my_vect<class my_coord>::push(class my_coord const &)" (?push@?$my_vect@Vmy_coord@@@@QAEXABVmy_coord@@@Z) referenced in function "public: void __thiscall my_interf::push(void)" (?push@my_interf@@QAEXXZ)
1>my_interf.obj : error LNK2019: unresolved external symbol "public: class my_coord * __thiscall my_vect<class my_coord>::pop(void)" (?pop@?$my_vect@Vmy_coord@@@@QAEPAVmy_coord@@XZ) referenced in function "public: void __thiscall my_interf::pop(void)" (?pop@my_interf@@QAEXXZ)
1>Program1.obj : error LNK2019: unresolved external symbol "public: void __thiscall my_interf::finish(void)" (?finish@my_interf@@QAEXXZ) referenced in function _wmain
1>Program1.obj : error LNK2019: unresolved external symbol "public: void __thiscall my_interf::defaul(void)" (?defaul@my_interf@@QAEXXZ) referenced in function _wmain

 
0

friend to nie metoda tylko funkcja.

0

No ok, a wracając do tematu co może być przyczyną błędów?

0

Szablon klasy powinien być cały w pliku nagłówkowym. Żeby można było używać szablonu w innej jednostce kompilacji kod szablonu musi być albo widoczny, albo wcześniej muszą zostać wygenerowane odpowiednie (potrzebne) konkretyzacje szablonu. Ponieważ to co piszesz ma być "ogólne" przenieś wszystko z my_vect.cpp do my_vect.h. (I potem ten cpp usuń, jest on niepotrzebny)

0

Dzięki, znaczna czesć błędów znikła, zostały jeszcze 2

 
1>------ Build started: Project: Program1, Configuration: Debug Win32 ------
1>Program1.obj : error LNK2019: unresolved external symbol "public: void __thiscall my_interf::finish(void)" (?finish@my_interf@@QAEXXZ) referenced in function _wmain
1>Program1.obj : error LNK2019: unresolved external symbol "public: void __thiscall my_interf::defaul(void)" (?defaul@my_interf@@QAEXXZ) referenced in function _wmain

0

No zobacz sobie do pliku my_interf.cpp - w tym, który tutaj wkleiłeś, nie ma implementacji tych dwóch funkcji: my_interf::defaul() (chyba miało być default) oraz my_interf::finish().

0

tak a propos obczaj to:

#include <iostream>
#include <vector>
using namespace std;

class my_interf
  {
   private:
   struct MY_INTERF_MENU
     {
      const char *text;
      void (my_interf::*run)();
     };
   static MY_INTERF_MENU menutb[];
   vector<double> vect;
   bool run;
   public:
   operator bool()const { return run; }
   void menu();
   void push() { cout<<"metoda push"<<endl; }
   void pop() { cout<<"metoda pop"<<endl; }
   void disp() { cout<<"metoda disp"<<endl; }
   void find() { cout<<"metoda find"<<endl; }
   void finish() { run=false; cout<<"metoda finish"<<endl; }
   void defaul() { cout<<"metoda defaul"<<endl; }
   public:
   my_interf(size_t dim):vect(dim),run(true) {}
  };

my_interf::MY_INTERF_MENU my_interf::menutb[]= // to musi być w cpp
  {
   {"push",&my_interf::push},
   {"pop",&my_interf::pop},
   {"disp",&my_interf::disp},
   {"find",&my_interf::find},
   {"finish",&my_interf::finish},
   {0,&my_interf::defaul}
  };

void my_interf::menu()
  {
   unsigned m;
   for(m=0;menutb[m].text;++m) cout<<m<<" - "<<menutb[m].text<<endl;
   cout<<"Wybierz: ";
   unsigned op;
   cin>>op;
   if(op>m) op=m;
   (this->*menutb[op].run)();
   cout<<endl;
  }

int main()
  {
   my_interf ifc(1000);
 
   while(ifc) ifc.menu();
   cin.sync();cin.get();
   return 0;
  }
0

Ok, program się kompiluje... ale mam jeden problem odnośnie wprowadzania danych. Otóż zapomocą interfejsu chce wprowadzić współrzędne x,y (0 - push) a nastepnie odczytać je za pomocą (2 - disp) lecz wyświetla mi śmieci postaci x=-2.xxxxxxx, y=-2.xxxxxxxxx
Czy wiecie co może to podowodać, próbowałem coś pozmieniać ale bez skutku.

0

nie podałeś jak wygładają twoje operatory >> i << dla coord'a

0

Tak wyglądają


 
istream & operator>>(istream & wejscie, my_coord &obj)
{
        cout<<"Podaj x: ";
        wejscie>>obj.pcoord[0];
        cout<<"Podaj y: ";
        wejscie>>obj.pcoord[1];
 
        return wejscie;
}
 
ostream & operator<<(ostream & wyjscie, my_coord & obj)
{
        wyjscie<<"x= "<<obj.pcoord[0]<<" y= "<<obj.pcoord[1]<<endl;
 
        return wyjscie;
}

 
0

Ktoś pomoże?

0

Mój kod wygląda teraz tak:

my_coord.h

 
///////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////my_coord.h

#ifndef INCLUDE_MY_HEADER_my_coord_h
#define INCLUDE_MY_HEADER_my_coord_h

#include "my_mess.h"
#include <iostream>
using namespace std;

class my_coord
{
	double *pcoord;  //pcoord[0] -; pcoord[1] - y
	my_mess msg;
public:
	my_coord() { alloc(); pcoord[0] = pcoord[1] = 0; }
	my_coord(double x, double y);
	~my_coord();

	bool operator==(const my_coord &ob);
	bool operator !=(const my_coord &ob);
private:
	void alloc();

	friend istream & operator>>(istream & wejscie, my_coord & obj);
	friend ostream & operator<<(ostream & wyjscie, my_coord & obj);
};

#endif

my_coord.cpp

 
///////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////my_coord.cpp

#include "stdafx.h"
#include "my_coord.h"
#include <iostream>
using namespace std;

my_coord::my_coord(double x, double y)
{
	alloc();

	pcoord[0]=x;
	pcoord[1]=y;
}

my_coord::~my_coord()
{
	if(pcoord)
		delete [] pcoord;
}

bool my_coord::operator==(const my_coord &ob)
{
	if(pcoord[0] != ob.pcoord[0])
		return false;
	else if(pcoord[1]!=ob.pcoord[1])
		return false;
	
	return true;
}

bool my_coord::operator!=(const my_coord &ob)
{
	if(pcoord[0]==ob.pcoord[0])
		return false;
	else if(pcoord[1]==ob.pcoord[1])
		return false;
	
	return true;
}

void my_coord::alloc()
{
	pcoord=0;
	
	try
	{
		pcoord= new double [2];
	}

	catch(bad_alloc)
	{
		msg.mess(my_mess::ERR_ALLOC_MEM);
	}
}

istream & operator>>(istream & wejscie, my_coord &obj)
{
        cout<<"Podaj x: ";
        wejscie>>obj.pcoord[0];
        cout<<"Podaj y: ";
        wejscie>>obj.pcoord[1];
 
        return wejscie;
}
 
ostream & operator<<(ostream & wyjscie, my_coord & obj)
{
        wyjscie<<"x= "<<obj.pcoord[0]<<" y= "<<obj.pcoord[1]<<endl;
 
        return wyjscie;
}

my_interf.h

 
///////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////my_interf.h

#ifndef INCLUDE_MY_HEADER_my_interf_h
#define INCLUDE_MY_HEADER_my_interf_h
#define MAX_INTERF_CHAR 512

#include "my_vect.h"
#include "my_coord.h"


class my_interf
{
public:
	enum MY_INTERF
	{
		MY_INTERF_PUSH,
		MY_INTERF_POP,
		MY_INTERF_DISP,
		MY_INTERF_FIND,
		MY_INTERF_FINISH,
		MY_INTERF_TOT	
	};
private:
	my_vect<my_coord> vect;
	char str_interf[MY_INTERF_TOT][MAX_INTERF_CHAR];  //komunikaty, wyświetlane na monitorze
	my_mess msg;
public:
	bool run;

	my_interf();
	my_interf(size_t dim);
	void menu();
	void push();
	void pop();
	void disp();
	void find();
	void finish();
	void defaul();
};


#endif

my_interf.cpp

///////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////my_interf.cpp

#include "stdafx.h"
#include "my_interf.h"
//#include <iostream>
//using namespace std;

my_interf::my_interf(size_t dim)
{
	sprintf_s(str_interf[MY_INTERF_PUSH], MAX_INTERF_CHAR*sizeof(char), "%d - push", MY_INTERF_PUSH);
	sprintf_s(str_interf[MY_INTERF_POP], MAX_INTERF_CHAR*sizeof(char), "%d - pop", MY_INTERF_POP);
	sprintf_s(str_interf[MY_INTERF_DISP], MAX_INTERF_CHAR*sizeof(char), "%d - disp", MY_INTERF_DISP);
	sprintf_s(str_interf[MY_INTERF_FIND], MAX_INTERF_CHAR*sizeof(char), "%d - find", MY_INTERF_FIND);
	sprintf_s(str_interf[MY_INTERF_FINISH], MAX_INTERF_CHAR*sizeof(char), "%d - finish", MY_INTERF_FINISH);
	vect.init(dim);
	run = true;
}

void my_interf::menu()
{
	int i;
	for(i=0; i<MY_INTERF_TOT; i++)
	{
		cout << str_interf[i] << endl;
	}
}

void my_interf::push()
{
	my_coord ob(0,0);
	cin >> ob;
	vect.push(ob);
}

void my_interf::pop()
{
	my_coord *ptr = NULL;
	ptr = vect.pop();
	if(ptr)
	{
		cout << *ptr;
	}
	else
	{
		msg.mess(my_mess::WARN_ARR_EMPT);
	}
}

void my_interf::disp()
{
	vect.disp();
}

void my_interf::find()
{
	my_coord ob(0, 0);
	my_coord *ptr = NULL;
	cout << "input x, y - object for search\n";
	cin >> ob;
	ptr = vect.get_begin();
	size_t dist;
	while(ptr)
	{
		ptr = Find(ptr, vect.get_end(), ob);
		if(ptr)
		{
			dist = ptr-vect.get_begin();
			cout << "it = " << dist << " " << *ptr;
			ptr++;
		}
		else
			cout << "search end\n";
	}
}

void my_interf::finish()
{
	cout<<"Koniec programu"<<endl;
	system("pause");
	exit(1);

}

void my_interf::defaul()
{
	cout<<"Wybierz poprawny numer!!!"<<endl;
}
 

my_mess.h

 
///////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////my_mess.h

#ifndef INCLUDE_MY_HEADER_my_mess_h
#define INCLUDE_MY_HEADER_my_mess_h
#include <iostream>
using namespace std;
class my_mess
{
public:
	enum MY_MESSAGE
	{
		ERR_ALLOC_MEM,     //błąd alokacji pamięci
		WARN_ARR_FULL,     //tablica jest wypelniona (last > ndim)
		WARN_ARR_EMPT,     //tablica jest pusta (last = 0)
		WARN_ARR_UNKN,     //niepoprawny kod działania (interfejs)
		TOT_NUMB                 //ogólna ilość komunikatów
	};

	static char *strtab[TOT_NUMB];  //tablica tekstowa komunikatów

public:
	void mess(enum MY_MESSAGE ms);    //Przy wywołani tej funkcji na ekran //pozostaje wyprowadzony komunikat. Jeśli to błąd, obliczenia trzeba //skończyć, jeśli nie – kontynuować. ms – składowa enumeration, która podaje //numer komunikatu
};

#endif

my_mess.cpp

///////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////my_mess.cpp

#include "stdafx.h"
#include "my_mess.h"
//#include <iostream>
//using namespace std;

char *my_mess::strtab[] =
{
	"E  memory alloc error",          //ERR_ALLOC_MEM
	"W  array is full",               //WARN_ARR_FULL
	"W  array is empty",              //WARN_ARR_EMPT
	"W  niepoprawny kod operacji"     //WARN_ARR_UNKN
};

void my_mess::mess(enum MY_MESSAGE ms)
{
	if(strtab[ms][0] == 'E')
	{
		cout << "ERROR: " << &strtab[ms][1] << endl;
		system("pause");
		exit(1);
	}
	else if(strtab[ms][0] == 'W')
	{
		cout << "WARNING: " << &strtab[ms][1] << endl;
	}
}
 

my_vect.h

///////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////my_vect.h

#ifndef INCLUDE_MY_HEADER_my_vect_h
#define INCLUDE_MY_HEADER_my_vect_h

#include "my_mess.h"
#include <fstream>

template <class T>
class my_vect
{
	T *dat;        //wskaznik do danych typu ogolnego
	size_t ndim;   //rozmiar tablicy, na ktory pozostala zaalokowana
	size_t last;   //wskazuje na pierwsza pusta pozycje w tablice
	my_mess msg;

public:
	my_vect(size_t dm); //konstruktor - alokuje pamiec dla tablicy typu T 
						//na dm elementow
	my_vect() { dat = NULL; ndim = last = 0; }
	~my_vect();
	void init(size_t dm);	//alokuje pamiec o dm elementow, jesli dat = NULL
	T *get_begin();			//zwraca wskaźnik do początku tablicy dat
	T *get_end();		//zwraca wskaźnik do dat[last]
	void disp();			//wyswietla stan tablicy
	void push(const T &ob); //dodaje element typu T do pierwszej wolnej 
							//pozycji w tablice
	T *pop();               //zwraca wskaznik do ostatniego elementu tablicy 
							//i usuwa jego, lub NULL (tablica pusta)
	T & operator [] (const size_t ind); //0 <= ind < last
	void remove(size_t ind); //usuwa element tablicy o indeksie ind, kompresuje tablicu
private:
	bool alloc();            //alocuje pamięć
	bool realloc();
};

template <class T>
my_vect<T>::my_vect(size_t dm)
{
	//dat=NULL;
	ndim=dm;
	alloc();
	last=0;
}

template <class T>
my_vect<T>::~my_vect()
{
	if(dat)
		delete [] dat;
}

template <class T>
void my_vect<T>::init(size_t dm)
{
	if(dat == NULL)
	{
		ndim=dm;
		alloc();
		last=0;
	}
}

template <class T>
T *my_vect<T>::get_begin()
{
	return dat;
}

template <class T>
T *my_vect<T>::get_end()
{
	return dat+last;
}

template <class T>
void my_vect<T>::disp()
{
	T *ptr=get_begin();

	for(;ptr != get_end(); ptr++)
		cout<<*ptr<<" ";
	cout<<endl;
}

template <class T>
void my_vect<T>::push(const T &ob)
{
	if(last>=ndim)
		if(!realloc())
		{
			msg.mess(my_mess::ERR_ALLOC_MEM);
		}

	if(dat)
	{
		dat[last]=ob;
		++last;
	}
}

template <class T>
T *my_vect<T>::pop()
{
	if(dat && last)
		return &dat[--last];
	else
		return NULL;
}

template <class T>
T & my_vect<T>::operator[](const size_t ind)
{
	if(dat && (ind>=0) && (ind<last))
		return dat[ind];
}

template <class T>
bool my_vect<T>::alloc()
{
	if(!dat)
	{
		try
		{
			dat= new T[ndim];
		}
		catch(bad_alloc)
		{
			msg.mess(my_mess::ERR_ALLOC_MEM);
		}
	}
	return true;
}

template <class T>
bool my_vect<T>::realloc()
{
	if(!dat)
		if(!alloc())
		{
			msg.mess(my_mess::ERR_ALLOC_MEM);
			return false;
		}
		else
			return true;
	else
		return false;
}


template <class T, class K>
T *Find(const T *p_begin, const T *p_end, const K &key)
{
	if(p_begin==NULL)
	{
		cout<<"Podany wskaznik do tablicy jest pusty"<<endl;
		return NULL;
	}

	T *wsk=const_cast<T*>(p_begin);
	while(*wsk != *p_end)
	{
		if(*wsk==key)
			return wsk;
		++wsk;
	}

	return NULL;
}

#endif
 

main.cpp

// LAB 7 - Program1.cpp : Defines the entry point for the console application.
//

#include "stdafx.h"
#include "my_interf.h"



int _tmain(int argc, _TCHAR* argv[])
{
	int op;  //operacje
	my_interf ifc(1000);
	
	while(ifc.run)
	{
		ifc.menu();
		cin >> op;
		switch(op)
		{
		case my_interf::MY_INTERF_PUSH: //push
			ifc.push();
			break;
		case my_interf::MY_INTERF_POP:
			ifc.pop();
			break;
		case my_interf::MY_INTERF_DISP:
			ifc.disp();
			break;
		case my_interf::MY_INTERF_FIND:
			ifc.find();
			break;
		case my_interf::MY_INTERF_FINISH:
			ifc.finish();
			break;
		default:
			ifc.defaul();
		};
	}	

	system("pause");	
	return 0;
}

 
0

my_coord nie ma głębokiego kopiowania, ani operatora= zaś tu: dat[last]=ob; używasz kopiowanie.

0

Czyli ma być takie coś?

my_coord my_coord::operator=(const my_coord &prawy)
{
	if(prawy.pcoord)										
	{
		if(!pcoord)											
			alloc();										

		memcpy(pcoord, prawy.pcoord, _msize(prawy.pcoord));	
	}
	else
	{
		if(pcoord)											
			delete [] pcoord;							

		pcoord=NULL;
	}

	return *this;											
}
 

oraz

my_coord::my_coord(const my_coord &obj)
{
	pcoord=NULL;
	if(obj.pcoord)
	{
		try
		{
			alloc();
			pcoord[0]=obj.pcoord[0];
			pcoord[1]=obj.pcoord[1];
		}
		catch(bad_alloc)
		{
			msg.mess(my_mess::ERR_ALLOC_MEM);
		}
	}
}
 
0

Mam jeszcze problem z tym zadaniem a mianowicie odczytem danych z pliku

Napisałem coś takiego w my_vect.h

 

template <class T>											////
void my_vect<T>::read()
{
	flinp.open("read.txt", ios_base::in|ios_base::binary);	//Wywołujemy metode open. Otwieramy ten plik w trybie(formie) binarnej a nie tekstowej. 'ios_base::' oznacza flagę.

	if(!flinp.is_open())
		msg.mess(my_mess::ERR_OPEN_FILE);					//Sprawdzamy czy ten plik był na prawdę otwarty, jeśli nie był to error
	
	last=0;
	T tmp;

	for(;;)												//Nieskończona pętla.
	{
		flinp>>tmp;
		
		if(flinp.eof())
			break;										//Jeżeli wystąpił koniec pliku, to trzeba przerwac pętle.

		if(flinp.bad())
			msg.mess(my_mess::ERR_READ_FILE);

		push(tmp);										//Zaczynamy wypełniać od początku tablice, bez względu co tam było.
	}

	ios_base::streamoff file_len=flinp.tellg();			//Ilość plików jaką odczytaliśmy

	flinp.close();										//Jeżeli otworzyliśmy plik, to trzeba go zamknąć, bo w przeciwnym razie nie będziemy w stanie otworzyć go drugi raz.
}

Ale nie wiem czemu mi nie chce zadziałać, tzn wyświetla mi coś takiego jak wybiorę opcje read()

 Podaj x: Podaj y: Podaj x: Podaj y: 0 -push

Dodam, że mój plik read.txt wyglada tak

 
1
5
8
6

Nie ma nowej linii po liczbie "6".

W razie potrzeby podam cały kod - czyli ostrzeżenia itp.

0

bo używasz operatora >> tu:
flinp>>tmp;
który u ciebie wygląda tak:

istream & operator>>(istream & wejscie, my_coord &obj)
{
        cout<<"Podaj x: ";
        wejscie>>obj.pcoord[0];
        cout<<"Podaj y: ";
        wejscie>>obj.pcoord[1];
 
        return wejscie;
}

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