2017-10-19 132 views
0

我有一個Message類持有所有可能的元素分配內存的消息可以有:如何避免未使用的屬性

class Message { 
    int msg_id; 
    int msg_length; 

    char *username; 
    char *password; 
    char *usr_list; 
    char *to; 
    char *from; 
    char *grp_name; 
    int digit_1; 
    int digit_2; 
    char *msg; 
}; 

但不同的消息類型具有不同的身體元素使對象出來的正在浪費大量的記憶。例如,我的程序接收到下列數據:

Msg -> (1, name, password) 

當程序讀取1,它創建了一個Message對象,設置它的名稱和密碼,並將其轉發到其他類。現在剩下的屬性是空的並且未被使用,但仍然消耗內存。

我該如何解決這個問題?

更新: 訪客模式將幫助我在這種情況下,我不知道如果目標這樣的問題。

+6

這不是一個有效的C++'類'聲明。 – Barmar

+2

聽起來就像使用'union'和類型信息一樣。 – Bathsheba

+4

你的大多數成員都是指針,如果你沒有爲它們分配任何東西,它們不佔用太多內存。 – Barmar

回答

3

閱讀關於tagged union s或總和類型。瞭解如何使用union types,特別是按照rule of five和/或使用std::variant。也許你需要placement new顯式調用析構函數。優選smart pointers(也參見this)到原始的(和std::stringchar*)。使用enum s(或甚至enum class es)而不是有界的ID。熟悉containers

您也可以嘗試定義一些類層次結構等都有幾個班的消息......

花一個星期編碼之前閱讀一些好的book on C++ programming

6

由於Basile的答案在全球範圍內是正確的,我認爲重要的是聲明以下內容。

如果您試圖實施通信協議,我會推薦使用常用的數據序列化庫。

這些庫允許您輕鬆聲明通信協議,它們包含對這些功能等的支持,並且受許多不同語言的支持。

可以找到完整的選項列表here

我已經成功地在過去使用這些的:

0

我會嘗試構造Overloading.Constructor可以以類似的方式被重載的函數重載。

重載的構造函數具有相同的名稱(類的名稱)但參數個數不同。

根據傳遞的參數的數量和類型,調用特定的構造函數。

+1

重載的構造函數不會減少類成員變量的數量 – UnholySheep

+0

是的,但它們只創建需要的對象,你通過了(沒有剩下空的屬性)。 – FirePower

+0

它仍然爲所有變量分配內存,不管它們是否被初始化 – UnholySheep

3

您可以利用C++的繼承和多態性。

根據屬性對不同的消息類型進行分類並創建類層次結構來表示它們。

class Message 
{ 
    public: 
    // virtual methods to process the message 

    private: 
    // Attributes common to all the messages 
}; 

class MessageType1: public Message 
{ 
    public: 
    // Methods to process the message 

    private: 
    //Attributes specific to Type1 messages 
}; 

class MessageType2: public Message 
{ 
    public: 
    // Methods to process the message 

    private: 
    //Attributes specific to Type2 messages 
}; 

創建消息對象 - 你可以實現一個工廠,它有助於不同爲messageType的創作對象

class MessageFactory 
{ 
    // Method to create MessageType1 object 
    // Method to create MessageType2 object 
}; 

存儲消息對象 - 可以使用的容器來存儲,並通過不同的消息循環使用標準庫API對象。

std::vector<Message*> msgVect; // Can hold the derived class object pointers 

進程消息 - 您可以使用單個循環對所有存儲的對象執行操作。

for (auto msg: msgVect) 
{ 
    // msg is pointer to the derived class objects stored earlier. 
    // You can invoke a method here to perform operations on the 
    // object. 
} 
+0

這是最乾淨的解決方案!將未使用的變量存儲在一個類中顯然是一個糟糕的設計。 – Hitokage

+0

這是通過我的思想,但事情是我有20個消息類型,並使20個類包含指定的屬性..我把它作爲一個聰明的解決方案 – Shahan