2009-10-19 8 views
9

Làm thế nào tôi có thể làm cho một chức năng với cờ như thế nào của Windows CreateWindow (... phong cách | phong cách, ...), ví dụ, một hàm createnum:Làm cách nào để thực hiện các chức năng với thông số cờ? (C++)

int CreateNum(flag flags) //??? 
{ 
    int num = 0; 
    if(flags == GREATER_THAN_TEN) 
     num = 11; 
    if(flags == EVEN && ((num % 2) == 1) 
     num++; 
    else if(flags == ODD && ((num % 2) == 0) 
     num++; 
    return num; 
} 
//called like this 
int Number = CreateNum(GREATER_THAN_TEN | EVEN); 

Đây có phải là có thể, và nếu vậy, làm thế nào?

Trả lời

27

Bạn có thể xác định một enum xác định giá trị "đơn chút" (lưu ý rằng các cấu trúc kèm theo là hành động ở đây chỉ như là một bối cảnh đặt tên, do đó bạn có thể viết như MyFlags::EVEN):

struct MyFlags{ 
    enum Value{ 
     EVEN       = 0x01, 
     ODD       = 0x02, 
     ANOTHER_FLAG     = 0x04, 
     YET_ANOTHER_FLAG    = 0x08, 
     SOMETHING_ELSE     = 0x10, 
     SOMETHING_COMPLETELY_DIFFERENT = 0x20 
    }; 
}; 

và sau đó sử dụng nó như thế này:

int CreateNum(MyFlags::Value flags){ 
    if (flags & MyFlags::EVEN){ 
     // do something... 
    } 
} 

void main(){ 
    CreateNum((MyFlags::Value)(MyFlags::EVEN | MyFlags::ODD)); 
} 

hoặc đơn giản là như thế này:

int CreateNum(int flags){ 
    if (flags & MyFlags::EVEN){ 
     // do something... 
    } 
} 

void main(){ 
    CreateNum(MyFlags::EVEN | MyFlags::ODD); 
} 

Bạn cũng có thể chỉ đơn giản là khai báo hằng số nguyên, nhưng enum là rõ ràng hơn trong quan điểm của tôi.

Lưu ý: Tôi đã cập nhật bài đăng để nhận một số nhận xét, cảm ơn!

+5

Có lẽ bạn có thể làm cho enum của bạn dài hơn, để làm cho rõ ràng nó đã được quyền hạn của hai? – KeatsPeeks

+1

+1. như là một sang một bên, nó là không cần thiết để so sánh cờ với "== MyFlags :: EVEN", vì nó sẽ là số không hoặc không khác, mà tự động coerces để bool khá độc đáo. – rmeador

+0

Tôi không nghĩ rằng có thể vượt qua hai (hoặc nhiều hơn) cờ bằng cách sử dụng | nếu bạn sử dụng phương pháp này. – danadam

5

Bạn có thể sử dụng const int như thế này:

const int FLAG1 = 0x0001; 
const int FLAG2 = 0x0010; 
const int FLAG3 = 0x0100; 
// ... 

Và khi bạn sử dụng nó:

int CreateNum(int flags) 
{ 
    if(flags & FLAG1) 
     // FLAG1 is present 

    if(flags & FLAG2) 
     // FLAG2 is present 

    // ... 
} 

Tất nhiên bạn có thể đặt một hoặc nhiều cờ trong cờ của bạn bằng cách sử dụng toán tử |.

+4

Thay đổi '#define FLAG1 0x0001' thành' const int FLAG1 = 0x0001; ' –

+0

đồng ý với Alexey ... không sử dụng macro cho việc này. – Bill

+0

Có bạn đúng, tốt hơn. Tôi đã thay đổi nó. –

0

Bạn đã kiểm tra sai. Những gì bạn muốn là một cái gì đó giống như (flags & EVEN), trong đó EVEN là một số nguyên với một bộ bit (1, 2, 4, 8, 16 - một số sức mạnh của 2). (Số nguyên có thể là int hoặc enum. Bạn có thể có macro, nhưng thường không phải là một ý tưởng hay.)

Bạn có thể sử dụng ký pháp mà bạn đã liệt kê, bằng cách quá tải flags::operator==(flagvalue f), nhưng đó là một ý tưởng tồi.

1

Sử dụng quyền hạn của hai là hằng số cá nhân, như

enum Flags { EVEN = 0x1, ODD = 0x2, GREATER_TEN = 0x4 }; 

và bạn sử dụng hợp lý và điều hành '&' để thử nghiệm, như

if(flags & GREATER_THAN_TEN) 
    num = 11; 
if((flags & EVEN) && (num % 2) == 1) 
    num++; 
else if ((flags & ODD) && (num % 2) == 0) 
    num++; 
return num; 
0
enum flags { 
    EVEN =  0x0100, 
    ODD =   0x0200, 
    BELOW_TEN = 0x0400, 
    ABOVETEN = 0x0800, 
    HUNDRED =  0x1000, 
    MASK =  0xff00 
}; 

void some_func(int id_and_flags) 
{ 
    int the_id = id_and_flags & ~MASK; 
    int flags = id_and_flags & MASK; 
    if ((flags & EVEN) && (the_id % 2) == 1) 
     ++the_id; 
    if ((flags & ODD) && (the_id % 2) == 0) 
     ++the_id; 
    // etc 
} 

Minh hoạ mặt nạ của các lĩnh vực bit quá có thể hữu ích khi bạn chỉ cần sử dụng một chút chức năng bổ sung đơn giản mà không cần thêm bất kỳ cấu trúc dữ liệu bổ sung nào.

10

Tôi upvoted câu trả lời orsogufo, nhưng tôi luôn thích làm như sau để xác định các giá trị:

enum Value{ 
    EVEN       = (1<<0), 
    ODD       = (1<<2),   
    ANOTHER_FLAG     = (1<<3),   
    YET_ANOTHER_FLAG    = (1<<4),   
    SOMETHING_ELSE     = (1<<5),   
    SOMETHING_COMPLETELY_DIFFERENT = (1<<6), 

    ANOTHER_EVEN     = EVEN|ANOTHER_FLAG 
}; 

< < là các nhà điều hành chuyển đổi. Gia tăng phía bên phải cho phép bạn tạo ra các mặt nạ bit tuần tự bằng cách di chuyển 1 trên, một bit tại một thời điểm. Điều này có giá trị tương tự cho các cờ trống, nhưng đọc dễ dàng hơn cho đôi mắt của tôi và làm cho nó rõ ràng nếu bạn bỏ qua hoặc nhân đôi một giá trị.

Tôi cũng thích kết hợp một số kết hợp cờ phổ biến khi thích hợp.

+0

+1 từ tôi; Tôi cũng vậy, như định nghĩa "các kết hợp chung" :) –