2010-07-29 32 views
19

Với tất cả các loại cơ bản của C++, người ta có thể chỉ đơn giản là truy vấn:C++ chuyển đổi lớp để boolean

if(varname) 

và loại được chuyển thành một boolean để đánh giá. Có cách nào để nhân rộng chức năng này trong một lớp do người dùng định nghĩa không? Một trong các lớp của tôi được xác định bởi một số nguyên, mặc dù nó có một số thành viên khác, và tôi muốn có thể kiểm tra nếu số nguyên được đặt thành NULL theo cách như vậy.

Cảm ơn.

+0

Google cho "boolean an toàn" và bạn sẽ thấy các giải pháp khác nhau cho phép đánh giá boolean mà không cần chuyển đổi rõ ràng thành bool, tránh các cạm bẫy chuyển đổi phổ biến. –

Trả lời

18

Bạn có thể xác định toán tử chuyển đổi do người dùng xác định. Đây phải là hàm thành viên, ví dụ:

class MyClass { 
    operator int() const 
    { return your_number; } 
    // other fields 
}; 

Bạn cũng có thể thực hiện toán tử bool. Tuy nhiên, tôi sẽ STRONGLY đề nghị bạn không làm vì lớp học của bạn sẽ trở nên có thể sử dụng được trong các biểu thức số học có thể nhanh chóng dẫn đến một mớ hỗn độn. IOStreams xác định, ví dụ: chuyển đổi thành void*. Bạn có thể kiểm tra void* giống như cách bạn có thể thử nghiệm bool, nhưng không có chuyển đổi tiềm ẩn do ngôn ngữ xác định từ void*. Một cách khác là xác định operator! với ngữ nghĩa mong muốn.

Tóm lại: xác định các loại số nguyên sto của toán tử chuyển đổi (bao gồm cả booleans) là một ý tưởng tồi thực sự.

+0

Bạn tuyên bố rằng chuyển đổi thành các loại số nguyên là một ý tưởng tồi .. nhưng sau đó điều này là chính xác những gì đoạn mã của bạn làm. Đồng ý rằng 'toán tử bool()' có những hậu quả không mong muốn và có những giải pháp tốt hơn. Nhưng chuyển đổi thành void * cũng không hoàn hảo: 'Foo x; xóa x; 'bây giờ sẽ biên dịch. 'bool operator!()' là tốt hơn, nhưng bạn vẫn cần phải làm 'if (!! x)' để kiểm tra cho trường hợp dương. Như đã đề xuất trong một bình luận khác, thành ngữ Safe Bool là giải pháp tốt nhất. –

+3

1) OP rõ ràng không biết cú pháp để xác định toán tử chuyển đổi, nếu không anh ta sẽ có thể mã hóa giải pháp tầm thường nhất. Vì vậy, ông đã học được một cái gì đó mới. 2) Tôi cảnh báo anh ta về việc này là một ý tưởng tồi. 3) Bool an toàn là tốt hơn, nhưng có vẻ như một overengineering. Nếu chuyển đổi để void * là tốt cho thư viện chuẩn, nó tốt cho tôi quá. – zvrba

+5

Trong C++ 11 có 'toán tử tường minh rõ ràng()' (được đề cập trong câu trả lời @plats và bình luận @UncleBens) đạt được những gì OP muốn. Tôi nghĩ sẽ tốt nếu thông tin này được đưa vào câu trả lời được chấp nhận. – fhahn

9

Chỉ cần triển khai operator bool() cho lớp học của bạn.

ví dụ:

class Foo 
{ 
public: 
    Foo(int x) : m_x(x) { } 
    operator bool() const { return (0 != m_x); } 
private: 
    int m_x; 
} 

Foo a(1); 
if (a) { // evaluates true 
    // ... 
} 

Foo b(-1); 
if (b) { // evaluates true 
    // ... 
} 

Foo c(0); 
if (c) { // evaluates false 
    // ... 
} 
+3

-1, điều này phá vỡ dễ dàng theo những cách không rõ ràng. Tra cứu "Safe Bool Idiom". – greyfade

+3

C++ 0x có 'toán tử tường minh rõ ràng()' để tránh sự phá vỡ ngầm định của kiểu này? – UncleBens

+0

@grayfade: đã đồng ý - giải pháp này không lý tưởng và thành ngữ Safe Bool là một cách tiếp cận mạnh mẽ hơn. –

-1

C++ kiểm tra xem kết quả câu lệnh có bằng không hay không. Vì vậy, tôi nghĩ rằng bạn có thể xác định toán tử bình đẳng cho lớp của bạn và xác định cách lớp của bạn sẽ khác với 0 trong điều kiện nào.

+0

Không thực sự ... giá trị được chuyển thành boolean. Nó chỉ là nói chung việc chuyển đổi được thực hiện từ '0' thành' false' và từ bất kỳ điều gì khác thành 'true'. Sự khác biệt quan trọng là nếu bạn định nghĩa 'bool operator == (loại const &, int);' và 'bool operator == (int, gõ const &);' bạn có thể so sánh đối tượng của bạn với '0' nhưng bạn không thể sử dụng đối tượng –

3

Như những người khác đã nêu, sử dụng operator int() hoặc operator bool() là ý tưởng tồi vì chuyển đổi cho phép. Sử dụng một con trỏ là ý tưởng tốt hơn. Các giải pháp bí quyết tốt nhất cho vấn đề này cho đến nay là để trở thành viên (chức năng) con trỏ:

class MyClass { 
    void some_function() {} 

    typedef void (MyClass:: * safe_bool_type)(); 
    operator safe_bool_type() const 
    { return cond ? &MyClass::some_function : 0; } 
}; 
14

Phương pháp C++ 11 là:

struct Testable 
    { 
    explicit operator bool() const 
     { return false; } 
    }; 

int main() 
    { 
    Testable a, b; 
    if (a)  { /* do something */ } // this is correct 
    if (a == b) { /* do something */ } // compiler error 
    } 

Lưu ý explicit từ khóa, giúp ngăn chặn các trình biên dịch từ chuyển đổi hoàn toàn.

+2

Đây phải là câu trả lời được chấp nhận và trả lời nhiều nhất. –

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