2013-07-22 54 views
5

Tôi là một nhà phát triển C nhúng gần đây đã bắt đầu rối tung với mã C++ trên thiết bị nhúng và không chắc chắn về cách áp dụng chính xác khi lớp truy cập dữ liệu dễ bay hơi như bộ nhớ -bộ đăng ký được ánh xạ hoặc dữ liệu trên thiết bị bên ngoài, chẳng hạn như Bộ chuyển đổi Analog-to-Digital (ADC).C++ Const-correctness với acess dữ liệu dễ bay hơi và bên ngoài

Ví dụ, tôi có các lớp giao diện mà các mô-đun phần cứng của thiết bị bằng cách truy cập thanh ghi bộ nhớ ánh xạ của mình thông qua một con trỏ, như vậy:

class IOPin 
{ 
public: 
    /* Constructor, destructor, other methods...*/ 

    // should this be a const method? 
    bool ReadIOState() {return portregs_->state;} 

private: 
    /* Other private stuff...*/ 

    // Constructor points this to the right set of memory-mapped registers 
    volatile struct portregs_t 
    { 
     uint32_t control; 
     uint32_t state; 
     uint32_t someotherreg; 
    } *portregs_; 
}; 

Các tên đăng ký được tất nhiên tạo thành vì lợi ích của thí dụ. Tôi đang sử dụng một thiết bị Microchip PIC32 cho bất kỳ ai tò mò.

Từ hiểu biết có thể không chính xác của tôi, đánh dấu phương thức const có nghĩa là trạng thái quan sát được của đối tượng không được thay đổi theo như người gọi có liên quan. Vì vậy, phương pháp ReadIOState()không phảiconst vì nó truy cập volatile dữ liệu có thể thay đổi bất kỳ lúc nào và do đó người gọi sẽ quan sát thay đổi? Hoặc có phải là const vì phương pháp không thay đổi rõ ràng bất cứ điều gì?

Hiện tại, tôi đang nghiêng về phía không thực hiện phương pháp đó const vì lý do được nêu trong câu hỏi. Điều này đặc biệt đúng sau khi vấp ngã khi this GotW article, trong đó nói rằng ý nghĩa của const đang thay đổi để có nghĩa là "có thể đọc đồng thời". Ứng dụng nhúng của tôi là đơn luồng, nhưng tôi cho rằng đó có thể là một phép thử tốt cho số điện thoại const nói chung.

Ngoài ra, trình biên dịch xử lý các phương pháp const như thế nào? Đó là, những gì xảy ra khi tôi muốn thăm dò ý kiến ​​tình trạng của IO như thế này:

// wait for IO pin to go high 
while(!myIOpin.ReadIOState()) 
{} 

Nếu ReadIOState()const, sau đó có thể trình biên dịch tái sử dụng các giá trị trả về sau khi một cuộc gọi hoặc là nó đủ thông minh để thấy rằng nó đang truy cập dữ liệu volatile và không làm điều đó?

+0

Tôi tự hỏi liệu bạn có thể tạo ra các phương pháp dễ bay hơi giống như cách bạn có thể thực hiện các phương pháp const hay không. –

+1

void test() volatile {} biên dịch trên VS2012 nhưng tôi không biết nó có nghĩa là gì vì tôi chưa bao giờ sử dụng dễ bay hơi trước đây. –

+1

@NeilKirk Có, bạn có thể làm điều đó. Nó có nghĩa là hàm có thể được gọi trên một cá thể 'volatile'. Cũng giống như các hàm 'const' có thể được gọi trên các thể hiện' const'. Bạn thậm chí có thể có tất cả 4 tình trạng quá tải của một chức năng thành viên nếu bạn cảm thấy thích nó. – Angew

Trả lời

2

Bạn chỉ cần trỏ đến cấu trúc bên trong lớp và bạn không thay đổi con trỏ, vì vậy phương thức có thể là const. Trình biên dịch không nên sử dụng lại giá trị từ cuộc gọi trước đó, nó đủ thông minh.

+0

Cảm ơn bạn đã phản hồi! Điều đó đúng và tôi tiếp tục tự nhắc mình rằng chính con trỏ đó được tạo thành const. Tuy nhiên, tôi nghĩ câu hỏi của tôi hơi hơn một chút về khía cạnh triết học. Nghĩa là, việc sử dụng const cho một phương thức ngụ ý bất cứ điều gì về giá trị trả về của phương thức? Nếu giá trị trả lại có thể thay đổi giữa hai cuộc gọi liên tiếp thành một phương thức mặc dù lớp không phải là người đã thay đổi chúng, thì có phải là hợp lý khi nói rằng đó là const? –

+0

Const là từ khóa chỉ được sử dụng trong thời gian biên dịch, lúc chạy không có kiểm tra đặc biệt nào liên quan đến const được thực hiện (chỉ trong trường hợp một may mắn và giá trị const được lưu trữ tại trang bộ nhớ chỉ đọc bởi OS), từ khóa này chỉ được sử dụng để có thêm trợ giúp (các lỗi biên dịch) từ trình biên dịch tại thời gian biên dịch. Sử dụng const cho phương thức không ngụ ý bất cứ điều gì về giá trị trả về của phương thức. Đây là mặt ít trực quan của C++. – lextiz

+0

Gotcha, cảm ơn! –