2012-01-09 71 views
6

Tôi có một truy vấn, tôi đã thiết lập các tệp phẳng (nói tệp1, tệp2, v.v.) chứa tên cột và kiểu dữ liệu gốc. (cách các giá trị được lưu trữ và có thể được đọc trong C++ là sơ cấp) ví dụ: file1 phẳng tập tin có thể có dữ liệu như col1_name = id, col1_type = số nguyên, col2_name = Tên, col2_type = chuỗi và như vậy. Vì vậy, đối với mỗi tệp phẳng tôi cần tạo cấu trúc dữ liệu C++ (nghĩa là 1 tệp phẳng = 1 cấu trúc dữ liệu) trong đó tên biến thành viên có cùng tên với tên cột và kiểu dữ liệu của nó sẽ là kiểu dữ liệu gốc C++ như int , phao, chuỗi, v.v ... theo loại cột trong tệp phẳng. từ trên, ví dụ: tập tin căn hộ của tôi 1 nên cho tôi dưới đây khaiC++, tạo các lớp trong thời gian chạy

class file1{ 
    int id; 
    string Name; 
}; 

Có cách nào tôi có thể viết mã trong C++, nơi nhị phân một lần tạo ra sẽ đọc các tập tin phẳng và tạo cấu trúc dữ liệu dựa trên các tập tin (tên lớp sẽ giống như tên tệp phẳng). Tất cả các lớp được tạo bằng cách sử dụng các tệp phẳng này sẽ có chức năng chung của các hàm thành viên getter và setter.

Hãy cho tôi biết nếu bạn đã thực hiện điều gì đó tương tự sớm hơn hoặc có bất kỳ ý tưởng nào về điều này.

+2

Không thể, xin lỗi. Bạn sẽ cần phải sử dụng một cái gì đó như một bản đồ của chuỗi (tên thuộc tính) cho một kiểu dữ liệu biến thể thay thế. – Jon

+1

Bạn không thể tạo các định nghĩa lớp khi chạy trong C++, bạn có thể sử dụng ngôn ngữ kịch bản hoặc thậm chí là C++ để đọc các tệp phẳng và nhổ ra các tệp nguồn và biên dịch chúng sau này. –

+0

Tôi chưa bao giờ sử dụng ['boost :: any'] (http://www.boost.org/doc/libs/1_48_0/doc/html/any.html). Điều đó sẽ giúp giải quyết vấn đề của @ rocky? –

Trả lời

5

Các lớp C++ là các khái niệm biên dịch thuần túy và không có ý nghĩa khi chạy, do đó chúng không thể được tạo ra. Tuy nhiên, bạn chỉ có thể đi với

std::vector<std::string> fields; 

và phân tích khi cần thiết trong các chức năng truy cập của bạn.

+1

'boost :: any' có thể tốt hơn' std :: string'. –

8

Không, không trực tiếp. C++ là một ngôn ngữ được biên dịch. Mã cho mỗi lớp được tạo bởi trình biên dịch.

Bạn sẽ cần quy trình gồm hai bước. Đầu tiên, viết một chương trình đọc các tệp đó và dịch chúng thành tệp .cpp. Thứ hai, chuyển các tệp .cpp đó đến trình biên dịch.

+0

Điều này sẽ không ở thời gian chạy –

+1

@Seth: Đó là lý do tại sao từ đầu tiên của câu trả lời của tôi là "Không". Tuy nhiên, bạn _could_ biên dịch mã này thành một DLL và tải động đó. Điều đó có hữu ích không? Tôi không thể nói từ câu hỏi này. – MSalters

+0

Ý tưởng đáng kinh ngạc biên soạn và tải một dll, đẹp nhất. Đây có thể là một giải pháp thử nghiệm thú vị trong dự án hiện tại của tôi –

7

Không, không dễ dàng (xem theotheranswers vì lý do tại sao không).

Tôi khuyên bạn nên xem xét Python thay vì loại sự cố này. Python's type system kết hợp với đặc điểm sử dụng try/except của chính nó dễ dàng hơn đối với thách thức phân tích dữ liệu.

Nếu bạn thực sự phải sử dụng C++, sau đó bạn có thể tìm thấy một giải pháp sử dụng tính năng dynamic properties của QObject lớp Qt 's, kết hợp với lớp QVariant. Mặc dù điều này sẽ làm những gì bạn muốn, tôi sẽ thêm một cảnh báo rằng điều này đang nhận được loại nặng và có thể làm phức tạp hơn nhiệm vụ của bạn.

+0

@ downvoter, Hãy cẩn thận để giải thích tại sao điều này không hữu ích? Nó nói khá rõ ràng "Hãy cho tôi biết nếu bạn đã làm một cái gì đó tương tự trước đó hoặc có bất kỳ ý tưởng cho việc này." –

+2

Đập tôi. 1, vì đây là một điểm hợp lệ trong quan điểm của tôi. –

+0

Tôi cũng vậy - Tôi với bạn - (+1) –

4

Không, nhưng từ những gì tôi có thể nói, bạn phải có khả năng lưu trữ tên của nhiều cột. Những gì bạn có thể làm là có một biến thành viên map hoặc unordered_map mà bạn có thể lập chỉ mục bằng một chuỗi - tên cột - và lấy một số dữ liệu (như đối tượng cột hoặc thứ gì đó) trở lại. Bằng cách đó bạn có thể làm

obj.Columns["Name"] 
0

Tôi không chắc chắn có một mẫu thiết kế này, nhưng nếu danh sách các tên kiểu có thể là hữu hạn, và được biết đến tại thời gian biên dịch, bạn không thể khai báo tất cả những lớp học trong chương trình của bạn trước khi chạy, và sau đó chỉ cần khởi tạo chúng dựa trên dữ liệu trong các tệp?

+0

Tất cả, cảm ơn bạn đã trả lời câu hỏi của tôi và giúp tôi. Ngoài ra, mối quan tâm chính của tôi là triển khai nhị phân đơn và gửi cho các khách hàng khác nhau.Cấu trúc tệp phẳng do khách hàng đưa ra sẽ khác nhau, do đó, tệp nhị phân này phải là chung chung có thể xử lý cấu trúc dữ liệu khi đang bay. Ofcourse các chức năng chính của nhị phân là tương tự như tất cả các khách hàng, ngoại trừ chúng ta cần phải phục vụ cho khách hàng dữ liệu khác nhau là cho chúng ta, do đó tất cả các mess này. Tôi hy vọng tôi sẽ làm rõ vấn đề của mình. Tôi nghĩ rằng điều này có thể là có thể bằng cách sử dụng lập trình meta hoặc phản xạ trong C + +. nhưng tôi rất yên tĩnh với những khái niệm đó. –

+0

Tôi nghĩ bạn chỉ nên xem các tệp văn bản đó làm đầu vào được phân tích cú pháp. Cá nhân, tôi sẽ sử dụng các công đoàn để lưu trữ dữ liệu. Nhưng tất nhiên, bạn phải biết trước những gì mong đợi trong các tập tin văn bản và suy nghĩ cấu trúc hơn có thể chứa tất cả các dữ liệu khác nhau, nếu không nó sẽ không hoạt động. –

0

Điều bạn thực sự muốn là trường có bản chất chính xác thay đổi theo thời gian chạy.

Có một số cách tiếp cận, bao gồm Boost.Any, nhưng vì tính chất tĩnh của hệ thống kiểu C++ chỉ 2 thực sự được khuyến nghị và cả hai yêu cầu phải có ý tưởng trước về tất cả các loại dữ liệu có thể được yêu cầu.

Phương pháp đầu tiên là điển hình:

  • Object cơ sở loại
  • Int, String, Date bất cứ điều gì có nguồn gốc loại

và việc sử dụng đa hình.

Thứ hai yêu cầu một chút phép thuật Tăng cường: boost::variant<int, std::string, date>.

Khi bạn đã bao gồm phần "biến thể", bạn cần triển khai lượt truy cập để phân biệt giữa các loại có thể khác nhau. Khách truy cập điển hình cho phương pháp tiếp cận hướng đối tượng truyền thống hoặc chỉ đơn giản là boost::static_visitor<>boost::apply_visitor kết hợp cho phương pháp tăng cường.

Khá đơn giản.

Các vấn đề liên quan