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

Đề tài: Làm sao để chia code class với template declaration ở một file còn definition ở một file khác?

  1. #1
    Ngày gia nhập
    06 2010
    Nơi ở
    Hà Nội
    Bài viết
    31

    Mặc định Làm sao để chia code class với template declaration ở một file còn definition ở một file khác?

    Mình thử code như nhau thì bị báo lỗi (NetBeans 6.9- Ubuntu)
    FIle header : array.h
    C++ Code:
    1. /*
    2.  * File:   array.h
    3.  * Author: hoduc
    4.  *
    5.  * Created on July 18, 2011, 9:22 AM
    6.  */
    7.  
    8. #ifndef ARRAY_H
    9. #define ARRAY_H
    10.  
    11.  
    12.  
    13. #endif  /* ARRAY_H */
    14.  
    15. template <typename Datatype, int size, Datatype zero>
    16.  
    17. class Array
    18. {
    19.  
    20. private:
    21.     Datatype *array;
    22. public:
    23.     //constructor
    24.     Array(void);
    25.  
    26.     //show the array
    27.     void show();
    28.  
    29.  
    30. };

    File "arrayCode.cpp" chứa định nghĩa các hàm:
    C++ Code:
    1. #include <iostream>
    2. #include "array.h"
    3. using namespace std;
    4.  
    5. template<typename Datatype, int size, Datatype zero>
    6.  
    7. Array<Datatype, size, zero>::Array()
    8. {
    9.     array = new Datatype[size];
    10.     int i;
    11.     for(i = 0; i < size; i++)
    12.         array[i] = zero;
    13.  
    14.  
    15. }
    16.  
    17. template<typename Datatype, int size, Datatype zero>
    18. void Array::show()
    19. {
    20.     int i;
    21.     for (i = 0; i < size; i++)
    22.         cout << array[i] << " ";
    23.  
    24.     cout << endl;
    25. }

    File main.cpp:
    C++ Code:
    1. /*
    2.  * File:   main.cpp
    3.  * Author: hoduc
    4.  *
    5.  * Created on July 18, 2011, 9:20 AM
    6.  */
    7.  
    8. #include <cstdlib>
    9. #include <iostream>
    10. #include "array.h"
    11.  
    12. using namespace std;
    13.  
    14. /*
    15.  *
    16.  */
    17. int main(int argc, char** argv) {
    18.     Array<int, 5, 0> m_array();
    19.     m_array.show();
    20.     return 0;
    21. }

    NetBeans nó báo lỗi như sau:
    Code:
    main.cpp:19:13: error: request for member ‘show’ in ‘m_array’, which is of non-class type ‘Array<int, 5, 0>()’
    Mong mọi người giúp đỡ.
    Đã được chỉnh sửa lần cuối bởi homanhduc : 19-07-2011 lúc 01:09 AM.
    Hô Hô

  2. #2
    Ngày gia nhập
    07 2011
    Bài viết
    160

    Trích dẫn Nguyên bản được gửi bởi homanhduc Xem bài viết
    File "arrayCode.cpp" chứa định nghĩa các hàm:
    Với các template class thì định nghĩa các hàm cũng để trong file .h bạn nhé (trừ một vài trường hợp explicit instantiation đặc biệt). Vì vậy các template class người ta thường đặt trong file .hpp

    Trích dẫn Nguyên bản được gửi bởi homanhduc Xem bài viết
    template<typename Datatype, int size, Datatype zero>
    void Array::show()
    Đoạn này bạn thiếu template params, cần viết
    void Array<Datatype, size, zero>::show()
    Có thể 1 số compiler vẫn chấp nhận cách viết của bạn nhưng như vậy không đúng chuẩn. Đối với template class mình thường viết inline (tức là khai báo + định nghĩa cùng 1 chỗ chứ không tách ra) cho đỡ phức tạp. Viết như vậy sẽ khó nhìn header hơn, để giải quyết vấn đề này mình làm 1 file document riêng.

    Trích dẫn Nguyên bản được gửi bởi homanhduc Xem bài viết
    Array<int, 5, 0> m_array();
    Dòng này của bạn là cú pháp khai báo 1 function có tên m_array, trả về kiểu Array<int, 5, 0>. Để khai báo biến thì bạn bỏ 2 dấu ngoặc đơn đi:
    Array<int, 5, 0> m_array;
    Cái lỗi nó báo chính là vì vấn đề này


    Ngoài lề: bạn nên quen với cách viết vòng for như sau:
    for (int i = 0; i < size; ++i)
    thay vì khai báo int i; rồi for. Biến i chỉ cần dùng trong scope của vòng for thì chỉ nên khai báo trong scope của for. Nên tạo thói quen sử dụng toán tử ++ theo kiểu pre-fix (++i) và chỉ sử dụng kiểu post-fix (i++) khi thực sự cần thiết.

  3. #3
    Ngày gia nhập
    07 2011
    Bài viết
    160

    Túm lại câu trả lời cho câu hỏi của bạn là: Không tách definition ở file cpp đối với template class. Có thể để definition ở các file .h (.hpp) khác nhau (ví dụ trường hợp partial specialization) tuy nhiên phải đảm bảo include các file đó trước khi sử dụng.

    Thêm 1 số vấn đề trong code của bạn:

    -
    Code:
    template <typename Datatype, int size, Datatype zero>
    instantiate template class này chỉ hợp lệ khi data type là kiểu primitive (kiểu số nguyên, bool, ...) và trong trường hợp này thì cũng không cần zero nữa, vì zero = 0. Giải pháp: bỏ zero ở template đi và khi cần zero thì dùng:
    Datatype zero=Datatype();
    Và trong default constructor của các custom Datatype thì init nó là zero tương ứng

    Mình thử viết lại constructor của Array như sau:
    Code:
    template<typename Datatype, int size>
    Array<Datatype, size>::Array(): array(new Datatype[size])
    {
      std::fill(array, array+size, Datatype());
    }
    - Class Array chưa có destructor để huỷ phần bộ nhớ cấp phát trong constructor. Theo mình nghĩ khi array fixed size thì không cần thiết cấp phát động. Khai báo luôn
    Code:
    private:
      Datatype array[size];
    cho đơn giản

    Cuối cùng là bạn có thể tham khảo class boost::Array trong thư viện free-source boost (www.boost.org) để làm bài tập này.

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

    vẫn có thể làm như bình thường bằng cách include file .cpp vào cuối file.h

    // file CLASS.h
    #ifndef CLASS
    #define CLASS
    //...
    #include "CLASS.cpp"
    i dont care who are u, where yr from, what u did , as long as u love me

  5. #5
    Ngày gia nhập
    06 2010
    Nơi ở
    Hà Nội
    Bài viết
    31

    Trích dẫn Nguyên bản được gửi bởi fbchicken Xem bài viết
    Với các template class thì định nghĩa các hàm cũng để trong file .h bạn nhé (trừ một vài trường hợp explicit instantiation đặc biệt). Vì vậy các template class người ta thường đặt trong file .hpp
    Mính đọc sách thấy họ có nói về vấn đề information-hiding, định làm thử. Theo như họ nói thì giả dụ mình đưa cho client thì cũng chỉ đưa cho họ header file (chứa function prototype), chứ không nên đưa cả definition..nên...)

    Trích dẫn Nguyên bản được gửi bởi fbchicken Xem bài viết
    Đoạn này bạn thiếu template params, cần viết
    void Array<Datatype, size, zero>::show()
    Có thể 1 số compiler vẫn chấp nhận cách viết của bạn nhưng như vậy không đúng chuẩn. Đối với template class mình thường viết inline (tức là khai báo + định nghĩa cùng 1 chỗ chứ không tách ra) cho đỡ phức tạp. Viết như vậy sẽ khó nhìn header hơn, để giải quyết vấn đề này mình làm 1 file document riêng.
    Hình như compiler gcc vẫn cho phép viết kiểu của mình


    Trích dẫn Nguyên bản được gửi bởi fbchicken Xem bài viết
    Dòng này của bạn là cú pháp khai báo 1 function có tên m_array, trả về kiểu Array<int, 5, 0>. Để khai báo biến thì bạn bỏ 2 dấu ngoặc đơn đi:
    Array<int, 5, 0> m_array;
    Cái lỗi nó báo chính là vì vấn đề này
    Mình tưởng phải khai báo giống như với constructor?


    Trích dẫn Nguyên bản được gửi bởi fbchicken Xem bài viết
    Ngoài lề: bạn nên quen với cách viết vòng for như sau:
    for (int i = 0; i < size; ++i)
    thay vì khai báo int i; rồi for. Biến i chỉ cần dùng trong scope của vòng for thì chỉ nên khai báo trong scope của for. Nên tạo thói quen sử dụng toán tử ++ theo kiểu pre-fix (++i) và chỉ sử dụng kiểu post-fix (i++) khi thực sự cần thiết.
    Mình cũng thích cách viết này, nhưng hồi đó hình như dùng Visual C++ Express 2008 thì phải, nó báo lỗi.

    Trích dẫn Nguyên bản được gửi bởi fbchicken Xem bài viết
    - Class Array chưa có destructor để huỷ phần bộ nhớ cấp phát trong constructor. Theo mình nghĩ khi array fixed size thì không cần thiết cấp phát động. Khai báo luôn
    Code:
    private:
      Datatype array[size];
    cho đơn giản
    Mình chưa viết destructor, mới thử viết tới chỗ kia thì nó báo lỗi

    P/S : Mình thấy nó báo lỗi ở hàm show mà chả biết lỗi thế nào?
    Đã được chỉnh sửa lần cuối bởi homanhduc : 19-07-2011 lúc 11:19 PM.
    Hô Hô

  6. #6
    Ngày gia nhập
    07 2011
    Bài viết
    160

    Mặc định Làm sao để chia code class với template declaration ở một file còn definition ở một file khác?

    Trích dẫn Nguyên bản được gửi bởi homanhduc Xem bài viết
    P/S : Mình thấy nó báo lỗi ở hàm show mà chả biết lỗi thế nào?
    Đã trả lời rồi mà:
    Trích dẫn Nguyên bản được gửi bởi fbchicken Xem bài viết

    Dòng này của bạn là cú pháp khai báo 1 function có tên m_array, trả về kiểu Array<int, 5, 0>. Để khai báo biến thì bạn bỏ 2 dấu ngoặc đơn đi:
    Array<int, 5, 0> m_array;
    Cái lỗi nó báo chính là vì vấn đề này

  7. #7
    Ngày gia nhập
    06 2010
    Nơi ở
    Hà Nội
    Bài viết
    31

    @fbchicken: mình bỏ dòng m_array.show() đi thì vẫn "build successful" mà bạn.
    Hô Hô

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

  1. Chuyển 1 file bất kì sang dạng mã hex (file ảnh, game,class,...)
    Gửi bởi virus trong diễn đàn Thắc mắc lập trình C#
    Trả lời: 13
    Bài viết cuối: 16-03-2013, 12:58 PM
  2. Chuyển đổi file JFrame Form thành file java class trong netbeans như thế nào???
    Gửi bởi quanganhpd93 trong diễn đàn Thắc mắc lập trình Java
    Trả lời: 1
    Bài viết cuối: 02-03-2013, 08:47 AM
  3. Lưu file và đọc file vào mảng 2 chiều trong winform
    Gửi bởi ngocan1608 trong diễn đàn Thắc mắc lập trình C#
    Trả lời: 5
    Bài viết cuối: 25-04-2011, 01:07 AM
  4. Kỹ thuật C++ Để chung 1 file chạy tốt nhưng chia gói thành các file .h, .cpp bị xong bị lỗi.
    Gửi bởi thanhphongcttv trong diễn đàn Thắc mắc lập trình C/C++/C++0x
    Trả lời: 5
    Bài viết cuối: 14-04-2010, 01:45 AM
  5. Quản lý source code C++ | Chia nhỏ các file .cpp, sử dụng file header
    Gửi bởi thongcam87 trong diễn đàn Nhập môn lập trình C/C++
    Trả lời: 5
    Bài viết cuối: 16-11-2008, 05:50 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