Từ 1 tới 3 trên tổng số 3 kết quả

Đề tài: Vấn đề với 'undefined reference to...'

  1. #1
    Ngày gia nhập
    03 2012
    Bài viết
    0

    Mặc định Vấn đề với 'undefined reference to...'

    Em đang viết 1 stack đơn giản, nhưng lúc compile nó báo lỗi như trong hình (dòng đỏ) :


    Đây là build log
    -------------- Build: Debug in stack_project ---------------

    Compiling: ../cast/stat_lib/sstack.cpp
    Compiling: ../cast/stat_lib/stack.cpp
    /root/cast/stat_lib/sstack_h.h:20:17: warning: ‘SStack::<unnamed>::verbose’ defined but not used
    Linking console executable: bin/Debug/stack_project
    obj/Debug/cast/stat_lib/stack.o: In function `main':
    /root/cast/stat_lib/stack.cpp:10: undefined reference to `SStack::sta<float>::get_sta()'
    collect2: ld returned 1 exit status
    Process terminated with status 1 (0 minutes, 2 seconds)
    1 errors, 1 warnings
    Đây là toàn bộ source code của stack code :
    stack.cpp
    Code:
    #include <iostream>
    using namespace std;
    
    ///////////////
    #include "sstack_h.h"
    
    using namespace SStack;
    
    int main()
    {
        sta<float> s2;
        s1.push_sta(55);
        cout << s2.get_sta();
        return 0;
    }
    sstack_h.h
    Code:
    #ifndef SSTACK_H_H_INCLUDED
    #define SSTACK_H_H_INCLUDED
    
    namespace SStack {
    
    namespace { int verbose = 0; }
    
    template<class type>
    class sta
    {
    private :
        enum { sta_size = 65536 }; // Chinh sua kich thuoc toi da cua Stack trong day
        type arr[sta_size]; // Mang luu stack.
        int pos; // Vi tri hien tai cua stack.
    public :
        sta() // Ham tao cua Stack. Khoi tao vi tri cua arr bang -1. Ly do: -1 + 1 = 0 trong vong lap dau tien (index cua arr bat dau tu 0).
        {
            pos = -1;
        }
    
        // Day 1 phan tu vao stack (var).
        void push_sta(type var);
    
        // Lam trong stack.
        void kill_sta();
    
        // Kiem tra tran tren/duoi cua stack. Thuc tra trong push_sta va get_sta cung
        // co the kiem tra duoc nhung neu ban muon kiem tra rieng re va khong muon thay doi
        // cac phan tu trong Stack thi co the dung ham nay.
        void ch_sta();
    
        // Chuyen kieu dong loat tat ca cac phan tu trong Stack.
        // Ho tro hien tai : 'f' (float); 'd' (double); 'i' (int);
        void sta_conv(char);
    
        // Sua lai vi tri Stack bang cach dat pos len dau hoac xuong cuoi stack.
        void sta_fix_pos(bool,bool);
    
        // Hien thi gia tri cua 1 phan tu trong Stack.
        // Thu tu phan tu can hien thi la doi so cua ham nay.
        type sta_show(type);
    
        // Thao tac voi cac phan tu tren Stack.
        // Hien chi ho tro cac tao tac rat co ban : 'c' (cong); 't' (tru); 'n' (nhan); 's' (chia)
        // Tham so thu ba cua sta_manip neu ban thiet dat la 1 thi bien se duoc trung binh cong
        // /tru/nhan/chia.
        type sta_manip(char,type,int);
    
        // Hien thi 1 phan tu trong stack. Co kiem tra tran.
        type get_sta();
    
        // Ham nay se tra ve gia tri 1 neu pos dang nam o index 0 cua arr
        // nguoc lai la 0 (pos khac 0)
        int gstat();
    
        // Ham nay se tra ve vi tri hien tai cua pos.
        // pos xac dinh vi tri cua arr.
        type ret_sta_pos();
    
        // Ham nay se tra ve kich thuoc lon nhat ma stack dang giu
        // Ban cung co the xem sta_size - 1 de biet kich thuoc lon nhat cua stack
        int ret_sta_sz();
    
        // Ham nay se dat vi tri cua stack len (sta_size - 1).
        void set_sta_st();
    
        // Ham huy cua Stack. Tam thoi chua viet duoc gi.
        ~sta() { }
    };
    
    }
    
    #endif // SSTACK_H_H_INCLUDED
    sstack.cpp
    Code:
    #include "sstack_h.h"
    
    template <class type>
    void SStack::sta<type>::set_sta_st()
    {
        pos = sta_size - 1;
    }
    
    template <class type>
    int SStack::sta<type>::ret_sta_sz() { return(sta_size - 1); }
    
    template <class type>
    type SStack::sta<type>::get_sta()
    {
        if(pos >= -1)
        {
            return(arr[pos--]);
        }
        else if(pos <= sta_size - 1) return(arr[pos++]);
        else
        {
            cout << "\n---Tran stack trong ham thanh vien sta::get_sta()---\n";
            cout << "Vi tri tran : " << pos;
        }
    }
    
    template <class type>
    void SStack::sta<type>::push_sta(type var)
    {
        if(pos <= sta_size - 1)
        {
            arr[++pos] = var;
        }
        else
        {
            cout << "\n---Tran stack---\n";
        }
    }
    
    template <class type>
    void SStack::sta<type>::kill_sta()
    {
        if(sta::gstat() == -1)
        {
            if(verbose == 1)
            {
                cout << endl << "*-" << endl
                     << "sta<type>::kill_sta() - Lam trong toan bo stack" << endl
                     << "-*" << endl;
            }
            for(int i = 0; i <= ret_sta_pos(); i++)
            {
                arr[i] = 0;
            }
        }
    }
    
    template <class type>
    type SStack::sta<type>::sta_show(type _pos)
    {
        if(verbose == 1)
        {
            cout << endl << "*-" << endl
                 << "sta_show tra gia tri cua 1 phan tu trong Stack."
                 << endl
                 << "de tra ve vi tri phan tu, su dung sta::ret_sta_pos()."
                 << endl
                 << "-*" << endl;
        }
        if(sta::gstat() == -1) return(arr[_pos]);
    }
    
    template <class type>
    void SStack::sta<type>::ch_sta()
    {
        if(pos < sta_size - 1) cout << "\nTran duoi tai " << pos;
        else if(pos > -1) cout << "\nTran tren tai " << pos;
        else cout << "\nKhong xay ra tran.";
    }
    
    template <class type>
    void SStack::sta<type>::sta_conv(char ch)
    {
        int i;
        if(sta::gstat() == -1)
        {
            switch(ch)
            {
            case 'i' :
                for(i = 0; i <= sta_size - 1; i++) arr[i] = (int)arr[i];
                break;
            case 'f' :
                for(i = 0; i <= sta_size - 1; i++) arr[i] = (float)arr[i];
                break;
            case 'd' :
                for(i = 0; i <= sta_size - 1; i++) arr[i] = (double)arr[i];
            default :
                cout << "\nLua chon sai!\n";
                break;
            }
            set_sta_st();
            if(verbose == 1) cout << "\nHoan thanh sta<type>::sta_conv().\n";
        }
    }
    
    template <class type>
    type SStack::sta<type>::sta_manip(char tp,type storer, int is_sp)
    {
        int j;
        switch(tp)
        {
        case 'c' :
            storer = 0;
            for(j = 0; j <= sta_size - 1; j++) storer += arr[j];
            break;
    
        case 't' :
            storer = 0;
            for(j = 0; j <= sta_size - 1; j++) storer -= arr[j];
            break;
    
        case 'n' :
            storer = 0;
            for(j = 0; j <= sta_size - 1; j++) storer *= arr[j];
            break;
    
        case 's' :
            storer = 0;
            for(j = 0; j <= sta_size - 1; j++) storer /= arr[j];
            break;
        }
        if(is_sp >= 1) storer /= (sta_size - 1);
    }
    
    template <class type>
    void SStack::sta<type>::sta_fix_pos(bool a, bool b)
    {
        if(a) sta();
        if(b) set_sta_st();
    }
    
    template <class type>
    int SStack::sta<type>::gstat()
    {
        if(pos == 0) return 1;
        else return -1;
    }
    
    template <class type>
    type SStack::sta<type>::ret_sta_pos() { return pos; }
    Và nếu main trong stack.cpp đưa vào sstack.cpp và di chuyển namespace + class trong sstack_h.h vào đầu sstack.cpp thì compile được. Em không hiểu tại sao (và có thể sửa đoạn code trên ntn).

    Em đang chạy Linux 2.6.8.38-13-generic và bản phân phối (X)ubuntu 11.04.

  2. #2
    Ngày gia nhập
    11 2010
    Bài viết
    589

    Lỗi kinh điển đây mà.

    Lý do của lỗi này là:
    - Trong quá trình biên dịch chương trình này có 2 "compile unit",
    Code:
    g++ stack.cpp sstack.h -c stack.o    # compile unit 1
    g++ sstack.cpp sstack.h -c sstack.o # compile unit 2
    g++ stack.o sstack.o -o stack              # link
    - Đặc điểm của template class/function các class/function tương ứng với các tham số template khác nhau là khác nhau, tức là sstack<int> và sstack<float> là 2 class khác nhau, không có liên quan gì đến nhau. Do đó, chỉ khi nào trong chương trình dùng đến một thể hiện nào đó của template thì trình dịch mới sinh ra mã tương ứng với nó. VD: nếu trong chương trình sử dụng sstack<int> thì mã của class sstack<int> mới được biên dịch thành file object.
    - Trong trường hợp này, với compile unit 1, ta mới chỉ có phần khai báo của template class sta, trình dịch sẽ coi như phần mã của sta<float> ở một compile unit khác, và sẽ link (liên kết) sau. Với compile unit 2, trong cả 2 file sstack.h và sstack.cpp đều không sử dụng một thể hiện nào của class sta nên không có đoạn mã nào của class sta<T> (T bất kỳ) được biên dịch ra file object. Do đó, ở quá trình link, linker sẽ không tìm thấy phần mã của class sta<float> (được dùng ở stack.cpp), lỗi undefined reference to `SStack::sta<float>::get_sta()' xảy ra.
    - Nếu cho phần khai báo và phần cài đặt của template class sta vào cùng một file, thì khi đó chỉ có 1 compile unit, có cả phần khai báo, phần mã và phần chương trình chính. Trình dịch sẽ sinh mã cho class sta<float> ngay trong compile unit này.

  3. #3
    Ngày gia nhập
    04 2010
    Nơi ở
    Binh Thanh, Hồ Chí Minh, Vietnam, Vietnam
    Bài viết
    504

    Chỉ cần đặt khai báo template và định nghĩa cùng một file (header), nhúng vào lúc biên dịch là sẽ không gặp lỗi
    Kết bạn với tôi <3
    Skype: giautm
    Facebook:
    https://fb.com/giautm.duongntt
    Email:
    giau.tmg@gmail.com

Các đề tài tương tự

  1. gcc 4.4.5 lỗi undefined reference to `__stack_chk_fail
    Gửi bởi AlexF trong diễn đàn Thắc mắc lập trình C/C++ trên Linux
    Trả lời: 5
    Bài viết cuối: 30-12-2010, 03:54 PM
  2. undefined reference to `AcceptEx@32'
    Gửi bởi haian trong diễn đàn Thắc mắc lập trình C/C++/C++0x
    Trả lời: 1
    Bài viết cuối: 12-04-2010, 04:45 PM
  3. Lỗi undefined reference to
    Gửi bởi lyland trong diễn đàn Thắc mắc lập trình Visual C++
    Trả lời: 2
    Bài viết cuối: 08-12-2009, 05:22 PM
  4. Lỗi: undefined reference to ... của MinGW
    Gửi bởi nguyenbinh07 trong diễn đàn Thắc mắc lập trình Visual C++
    Trả lời: 4
    Bài viết cuối: 08-05-2009, 08:21 PM

Quyền hạn của bạn

  • Bạn không thể gửi đề tài mới
  • Bạn không thể gửi bài trả lời
  • Bạn không thể gửi các đính kèm
  • Bạn không thể chỉnh sửa bài viết của bạn