2012-01-17 43 views
9

Tôi hiện đang tham gia phát triển C++ được nhúng trên nền tảng STM32. Nhóm của chúng tôi đang đánh giá việc sử dụng các mẫu để hỗ trợ trình điều khiển cho các thiết bị phần cứng cấp thấp khác nhau.Loại bỏ các thành viên tĩnh của mẫu instantiation instantiation

Tất cả các chuyên môn mẫu hợp lệ được biết trước, do đó chúng tôi có thể cung cấp tất cả các chuyên môn hợp lệ một cách rõ ràng bên trong tệp triển khai (triển khai và tách khai báo). Trong thực tế, chúng tôi chuyên môn rõ ràng là khá hữu ích vì nó giúp tài liệu bộ tham số khả thi.

// file i2c_dev.h 

template<typename traits> 
struct i2c_dev 
{ 
public: 
    static void init(); 
    static void send(); 
    static bool busy(); 
    ... 
private: 
    static i2c_transfer periodic_transfer; // class with used-defined constructor 
}; 

// traits class for configuration A 
struct i2c_dev_traitsA 
{ 
    enum 
    { 
     I2Cx_BASE = I2C1_BASE 
    , PORTx_BASE = GPIOB_BASE 
    , PORTx_PIN_TX = PB08 
    , PORTx_PIN_RX = PB09 
    }; 
}; 

// traits class for configuration B, different I2C peripherial and pinout 
struct i2c_dev_traitsB 
{ 
    enum 
    { 
     I2Cx_BASE = I2C2_BASE 
    , PORTx_BASE = GPIOA_BASE 
    , PORTx_PIN_TX = PA01 
    , PORTx_PIN_RX = PA02 
    }; 
}; 

// file i2c_dev.cpp 

// Implementation of template functions 
template<typename traits> 
void i2c_devy<traits>::init() { ... } 

... 

// explcitly specialize for all valid traits classes 
template class i2c_dev<i2c_dev_traitsA>; 
template class i2c_dev<i2c_dev_traitsB>; 

Mặc dù thường chỉ một trong các chuyên môn thực sự được sử dụng, mã được tạo cho chuyên môn không được sử dụng sẽ bị xóa khỏi hình ảnh cuối cùng bởi trình liên kết.

Tuy nhiên, các biến thành viên tĩnh - periodic_transfer trong mẫu trên - của mỗi chuyên môn mẫu vẫn còn trong tệp thực thi, như có thể thấy trong bản đồ bộ nhớ được tạo bởi công cụ arm-none-eabi-nm. Điều này có thể do thực tế là i2c_transfer không phải là POD nhưng có một hàm tạo do người dùng xác định. Khi hàm tạo được loại bỏ, biến điều đó thành kiểu POD, các thành viên tĩnh cũng biến mất.

Có cách nào để xóa các thành viên không phải POD tĩnh của các mẫu không được sử dụng một cách rõ ràng, nhưng không sử dụng?

Kính trọng, Arne

Chỉnh sửa # 1: Sau khi suy nghĩ lại vấn đề tôi đã đưa ra các giải pháp sau đây, mà rõ ràng là sửa chữa vấn đề.

Khi lớp i2c_transfer mà trên thực tế đã nó constructors chỉ cho rõ ràng và dễ sử dụng, có các thành viên dữ liệu của nó chuyển thành một lớp cơ sở POD i2c_transfer_pod như thế này:

struct i2c_transfer_pod 
{ 
protected: 
    uint16_t m_size; 
    char* m_buffer; 
}; 

struct i2c_transfer : public i2c_transfer_pod 
{ 
public: 
    i2c_transfer(); 
    i2c_transfer(i2c_direction_enum dir, char*buffer, uint16_t count); 

    bool failed(); 
    bool succeeded(); 
}; 

Sau đó, các thành viên tĩnh của không sử dụng i2c_dev<traits> các chuyên môn cũng được loại bỏ khỏi tệp thực thi cuối cùng (như tệp bản đồ gợi ý).

Chỉnh sửa # 2: Mặc dù trả lời tự cảm thấy hơi xấu hổ .. Tôi xin vui lòng yêu cầu nhận xét về giải pháp được đề xuất. Có cách nào tao nhã hơn không? Là trình biên dịch thực sự (như tôi đoán) tối ưu hóa các derivation bổ sung?

Chỉnh sửa # 3: Tôi đóng câu hỏi vì giải pháp phù hợp với tôi. Sẽ là tốt đẹp để có cái nhìn sâu sắc hơn vào lý do cho hành vi quan sát được.

Trình biên dịch trong câu hỏi là arm-none-eabi-gcc (Sourcery G++ Lite 2011.03-42) 4.5.2

+1

Nếu bạn tìm thấy giải pháp cho vấn đề của mình, bạn nên đăng câu trả lời đó. –

+1

Âm thanh giống như một trình biên dịch kỳ lạ, vì thực sự không có bất kỳ sự khác biệt nào cả, imho. – Xeo

+0

trình biên dịch bị lame là gì và phiên bản nào? –

Trả lời

2

trả lời (từ Chỉnh sửa # 1): Sau khi suy nghĩ lại vấn đề tôi đã đưa ra các giải pháp sau đây, mà rõ ràng là sửa chữa vấn đề.

Khi lớp i2c_transfer mà trên thực tế đã nó constructors chỉ cho rõ ràng và dễ sử dụng, có các thành viên dữ liệu của nó chuyển thành một lớp cơ sở POD i2c_transfer_pod như thế này:

struct i2c_transfer_pod 
{ 
protected: 
    uint16_t m_size; 
    char* m_buffer; 
}; 

struct i2c_transfer : public i2c_transfer_pod 
{ 
public: 
    i2c_transfer(); 
    i2c_transfer(i2c_direction_enum dir, char*buffer, uint16_t count); 

    bool failed(); 
    bool succeeded(); 
}; 

Sau đó, các thành viên tĩnh của không sử dụng i2c_dev<traits> các chuyên môn cũng được loại bỏ khỏi tệp thực thi cuối cùng (như tệp bản đồ gợi ý).

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