2009-12-31 38 views
5

Tôi tự hỏi nếu loại có thể được xác định là thông tin thời gian chạy trong C++.thời gian chạy xác định loại cho C++

(1) Mặc dù câu hỏi của tôi là khá chung chung, vì đơn giản, tôi sẽ bắt đầu từ một ví dụ đơn giản:

#include <stdio.h> 
#include <iostream> 
#include <cstring> 
using namespace std; 
int main(int argc, char * argv[]) 
{ 
if (strcmp(argv[1], "int")==0) 
{ 
    int t = 2; 
}else if (strcmp(argv[1], "float")==0) 
{ 
    float t = 2.2; 
} 
cout << t << endl; // error: ‘t’ was not declared in this scope 
return 0; 
} 

Đối với ví dụ này, có hai câu hỏi:

(a) "argv [1] đến t "là sai, nhưng có thể loại thông tin trong chuỗi C argv [1] được chuyển đổi sang từ khóa loại thực tế? Vì vậy, chúng ta không cần phải kiểm tra tất cả các loại theo mệnh đề if-else và strcmp.

(b) cách biến biến t được xác định bên trong phạm vi cục bộ của mệnh đề if vẫn hợp lệ bên ngoài. tức là cách "xuất" biến cục bộ ra bên ngoài phạm vi của nó?

(2) Nói chung, không cụ thể với ví dụ đơn giản ở trên, cách thông thường để xác định thời gian chạy là gì? Dường như với tôi rằng có thể có một số cách:

(a) người ta có thể đặt việc xử lý biến được xác định từ loại bên trong cùng phạm vi định nghĩa của nó. ví dụ.

#include <stdio.h> 
#include <iostream> 
#include <cstring> 
using namespace std; 
int main(int argc, char * argv[]) 
{ 
if (strcmp(argv[1], "int")==0) 
{ 
    int t = 2; 
    cout << t << endl; 
}else if (strcmp(argv[1], "float")==0) 
{ 
    float t = 2.2; 
    cout << t << endl; 
} 
return 0; 
} 

Và có thể sử dụng chức năng mẫu để tạo mã chung cho nhiều loại có thể sử dụng lại.

(b) hoặc người ta có thể sử dụng loại lớp trừu tượng và đa hình để gián tiếp xuất định nghĩa ra, nhưng tôi không chắc chắn chính xác như thế nào.

Cảm ơn lời khuyên của bạn!

Trả lời

7

1a: Không, các loại không phải là các đối tượng hoặc giá trị trong C++ (như chúng, ví dụ, trong Python). Tuy nhiên, bạn có thể sử dụng các giá trị khác nhau được chọn bởi giá trị của argv [1].

1b: Rất tiếc, không thể thực hiện điều đó.

2: dynamic_cast và typeid (cả hai toán tử) là các công cụ duy nhất hiện được ngôn ngữ cung cấp cho loại truy vấn (không phải bất thường, hầu hết các ngôn ngữ có rất ít, nhưng chuyên dụng, công cụ cho điều đó) và chỉ sử dụng chúng thường không được khuyến khích tùy thuộc vào tình huống (cũng không phải bất thường trong các ngôn ngữ khác).

2a: Có, và vì đó là đơn giản, hiển nhiên và hoạt động ở đây — không có lý do gì để sử dụng bất kỳ thứ gì khác, nhưng vì đó là mã ví dụ, giả sử bạn cần một giải pháp khác. Bạn có thể gọi một mẫu hàm được khởi tạo đúng loại, nhưng vì điều này khá giống với phần còn lại của 2a, tôi không đi sâu vào nó.

2b: Ví dụ sử dụng một mẫu lớp con, chỉ vì nó tiện dụng:

struct Base { 
    virtual ~Base() {} 
    friend std::ostream& operator<<(std::ostream& s, Base const& v) { 
    v._print(s); 
    return s; 
    } 
private: 
    virtual void _print(std::ostream&) const = 0; 
}; 

template<class T> 
struct Value : Base { 
    T data; 
    explicit 
    Value(T const& data) : data(data) {} 
private: 
    virtual void _print(std::ostream& s) const { 
    s << data; 
    } 
}; 

Sử dụng:

int main(int argc, char** argv) { 
    using namespace std; 
    auto_ptr<Base> p; 
    string const type = argc > 1 ? argv[1] : "int"; 
    if (type == "int") { 
    p.reset(new Value<int>(2)); 
    } 
    else if (type == "float") { 
    p.reset(new Value<double>(2.2)); 
    } 
    cout << *p << '\n'; 
    return 0; 
} 

này đang bắt đầu hợp nhất hai loại thành một loại, và cả hai đều trình bày cùng giao diện, Base, đây.Tuy nhiên, điều này không cho vay tốt đối với mọi giải pháp, và một biến thể như boost.variant có thể tốt hơn, đặc biệt khi các loại khác nhau yêu cầu có số lượng nhỏ và được biết trước.

+0

+1 Tôi sẽ đăng giải pháp đa hình. Làm cho ý nghĩa hơn nhiều so với boost.variant vì với boost.variant bạn cần phải kiểm tra kiểu cho mọi hoạt động. –

5

Bạn cần một lớp học có khả năng lưu trữ giá trị của các loại khác nhau. Ngắn từ một công đoàn, Boost's variant class sẽ là lựa chọn phù hợp.

+0

nếu không sử dụng tăng? – Tim

+0

Như tôi đã đề cập, một công đoàn. –

2

Khám phá Boost.Variant.

+1

Không có gì trong câu hỏi ban đầu cho thấy việc sử dụng Boost. Tại sao anh ta nên bao gồm một khung làm việc hoàn toàn mới cho một chức năng? Tôi xin lỗi, nhưng tôi không thấy điều này là hữu ích. –

+3

@druciferre: Câu hỏi sẽ hỏi cách làm điều gì đó trong C++. Mặc dù nhiều nhà phát triển C++ có kinh nghiệm có thể chưa từng nghe nói về việc tăng cường, họ nên có. Câu hỏi đã bao gồm các tham chiếu đến không gian tên std, Thư viện mẫu chuẩn, và bạn có thể cân nhắc khá nhiều về Boost để có khả năng sử dụng như STL. Bây giờ có rất nhiều thư viện trong Boost, vì vậy chỉ những thư viện nhất định sẽ có ý nghĩa đối với một vấn đề nhất định. – jmc

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