Panel użytkownika
Nazwa użytkownika:
Hasło:
Nie masz jeszcze konta?

Blad przy linkowaniu visual studio

Ostatnio zmodyfikowano 2010-01-06 23:11
Autor Wiadomość
Mapet
Temat założony przez niniejszego użytkownika
Blad przy linkowaniu visual studio
» 2010-01-06 15:33:53
Witam.
Mam mały problem przy linkowaniu kilku plików programu.

Plik main

C/C++
// vector.cpp : Defines the entry point for the console application.
//

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


int _tmain( int argc, _TCHAR * argv[] )
{
    const int r = 1;
    my_vect < int > obiekt( 4 );
    obiekt.push( 4 );
    obiekt.disp();
   
    system( "pause" );
    return 0;
}

Plik nagłówkowy szablonu klasy

C/C++
#ifndef MY_VECT_H
#define MY_VECT_H

template < class T > class my_vect
{
    T * dat; //wskaźnik do tablicy typu T
    size_t ndim; //ilość elementów, na które pozostała zaalokowana pamieć
    size_t last; //indeks, który wskazuje na pierwszy “pusty” element tablicy
   
public:
    my_vect( size_t dim ); //alokuje pamięć dla tablicy dat na dim elementów przy tworzeni obiektu
    ~my_vect(); //zwalnia pamieć
   
   
    T * get_begin() { return dat; } //zwraca wskaźnik do dat[0]
    T * get_end() { return & dat[ last ]; }
   
    void disp();
    void clear_all();
    void push( const T & ob ); // dodaje obiekt typu T w pozycje dat[last] i zwiększa last o jedynkę
    T * pop(); //dekrementuje last i zwraca ostatni element tablicy
    void erase( const T * ob ); //usuwa element *ob z tablicy dat i przesuwa elementy tablicy tak, żeby po usunięciu elementy
    //byli umieszczone ciągłe. (pakuje tablicę)
   
private:
    void realloc(); //jeśli last >= ndim – zwiększa ndim i realokuje pamięć
};
#endif

Plik z definicja klasy
C/C++
#include "stdafx.h"
#include "my_vect.h"
#include <iostream>
using namespace std;

template < class T >
my_vect < T >::my_vect( size_t dim )
{
    dat = new T[ dim ];
    ndim = dim; // okreslenie ilosci elementów stworzonej tablicy
    last = 0; // pokazanie na 1 element tablicy dat
}
template < class T >
my_vect < T >::~my_vect()
{
    delete[] dat;
    dat = NULL;
    last = 0;
}
template < class T >
void my_vect < T >::push( const T & ob )
{
    if( last >= ndim ) realloc();
   
    dat[ last ] = ob;
    last++;
}
template < class T >
T my_vect < T >::* pop()
{
    last--;
    return dat[ last ];
}
template < class T > // mozliwy blad z zmienna last!
void my_vect < T >::realloc()
{
    my_vect result = * this;
    ndim++;
    T * dat_cp = new T[ ndim ];
   
    for( size_t i = 0; i < ndim - 1; i++ ) dat_cp[ i ] = result.dat[ i ];
   
    result.~my_vect();
    result.dat = dat_cp;
    dat_cp = NULL;
}
template < class T >
void my_vect < T >::clear_all()
{
    last = 0;
}

template < class T >
void my_vect < T >::disp()
{
    for( size_t i = 0; i < last; i++ )
    {
        cout << dat[ i ] << " " << endl;
    }
    cout << "ndim = " << ndim << endl;
    cout << "last = " << last << endl << endl;
}

template < class T >
void my_vect < T >::erase( const T * ob )
{
    for( size_t i =* ob; i < last - 1; i++ )
    {
        dat[ * ob ] = dat[ * ob + 1 ];
    }
    last--;
}

Środowisko visual studio 2008

Wywala błąd

1>vector.obj : error LNK2019: unresolved external symbol "public: __thiscall my_vect<int>::~my_vect<int>(void)" (??1?$my_vect@H@@QAE@XZ) referenced in function _wmain
1>vector.obj : error LNK2019: unresolved external symbol "public: void __thiscall my_vect<int>::disp(void)" (?disp@?$my_vect@H@@QAEXXZ) referenced in function _wmain
1>vector.obj : error LNK2019: unresolved external symbol "public: void __thiscall my_vect<int>::push(int const &)" (?push@?$my_vect@H@@QAEXABH@Z) referenced in function _wmain
1>vector.obj : error LNK2019: unresolved external symbol "public: __thiscall my_vect<int>::my_vect<int>(unsigned int)" (??0?$my_vect@H@@QAE@I@Z) referenced in function _wmain
 
O ile się orientuje to dlatego ze nie ma definicji metod :< czyli problem z podpięciem pliku my_vect.cpp . Nie mam pojęcia co jest źle na dev działa :<

Edit :

Prosiłbym jeszcze o rozwiązanie problemu związanego z funkcja realloc(). Funkcja ta miała za zadanie zwiększenia tablicy w przypadku gdy zmienna "last" będzie >= ndim (ilości zarezerwowanej tablicy). I niby działa wszystko dobrze ale tylko w obrębie  tej funkcji gdyż po za nią tracę tablice której adres zwracam (czyżby dekonstruktor?):<

C/C++
void my_vect < T >::realloc()
{
    my_vect result = * this;
    ndim++;
    T * dat_cp = new T[ ndim ];
   
    for( size_t i = 0; i < ndim - 1; i++ ) dat_cp[ i ] = result.dat[ i ];
   
    result.~my_vect();
    result.dat = dat_cp;
    dat_cp = NULL;
}

Z góry przepraszam jeśli temat mało czytelny.
P-12743
Elaine
» 2010-01-06 19:16:19
Nie kłam, że to działa pod Devem - ten kod nie ma prawa zadziałać pod żadnym kompilatorem. Czy to cl, czy g++, czy może coś innego - w takiej postaci nie ruszy nigdzie. Co prawda jest pewne słówko, które pozwalałoby temu działać, ale że jest wspierane przez tylko dwa kompilatory to wiesz... Na przyszłość - jeśli masz jakiś wzorzec, to ma być w całości w nagłówku i tyle.
P-12748
Mapet
Temat założony przez niniejszego użytkownika
» 2010-01-06 22:44:33
Działa taki sam sposób rozdzielenia kodu na pliki tylko że sprawdzałem to na zwykłej najprostszej klasie napisanej w 5 m. W tym przykładzie też wylatywały błędy. Liczyłem na to że ktoś dokładnie wskaże mi błędy. Sorka za źle sformowane zdanie.

Poza tym wracając do twojej wypowiedzi, nie za bardzo ją zrozumiałem. Wzorzec czyli całą klasa ma być w nagłówku a definicje metod które są nie inline mają być w osobnym pliku .cpp? O to ci chodziło ? Bo jeśli tak to właśnie tak mam :<

A masz jakiś pomysł jak rozwiązać problem w funkcji realloc()?

Miałem długą przerwę w pisaniu w c++ i mam szczątki wiedzy dlatego mogę robić głupie błędy
P-12755
Elaine
» 2010-01-06 22:48:32
Nie. Wszystkie metody, bez wyjątku, muszą być w nagłówku.
P-12756
Mapet
Temat założony przez niniejszego użytkownika
» 2010-01-06 22:54:18
Rzeczywiście zadziałało ;O. To jest jakiś nowy standard? Bo w książce Grebosza jasno jest napisane że każda klasa to 2 pliki: header z ciałem klasy i cpp z definicjami metod. A przecież szablony i klasy nie wiele się różnią :<

P-12757
Elaine
» 2010-01-06 23:11:55
Bo Grębosz to pajac. Klasa może być w całości w nagłówku (patrz wszystkie wzorce, biblioteki header-only), rozdzielona na header i jeden .cpp (większość normalnego kodu) albo nawet na header i kilka .cpp (hmm... Bochs czegoś takiego używa). Kompilatorowi i linkerowi wsio ryba jak jest klasa podzielona, byleby te programy widziały deklaracje i definicje.
P-12758
« 1 »
  Strona 1 z 1