2015-11-01 116 views
0

我希望能夠使用公共外部函數以「人類可讀」形式顯示不同的子類。在每個實例化中打印'數據'是微不足道的,但我正在用一種優雅的方式來打印關於每個對象內容的細節(元)。C++擴展初始化列表

我可以達到我想要的以下三重AsData,FieldNamesGetFieldNamesAsData封裝在一個可讀形式的會員資料,FieldNames存儲在層次結構該點的數據字段名稱類的靜態列表和GetFieldNames包裝FieldNames具有可繼承功能:

class A { 
public: 
    A(const string& name) { /* Setup data */ } 

    // ... functions to access data members go here ... 

    virtual const vector<string>& GetFieldNames() { 
     return A::FieldNames; 
    } 

protected: 
    static const vector<string> FieldNames; 

    // ... some data members ... 
}; 

class B : public A { 
public: 
    B(const string& name, const string& description): A (name) { /* Setup extended data */ } 

    // ... functions to access additional data members go here ... 

    virtual const vector<string>& GetFieldNames() { 
     return B::FieldNames; 
    } 

protected: 
    static const vector<string> FieldNames; 

    // ... some additional data members ... 
}; 

所以使用可如下:

void PrintTable (vector<shared_ptr<A> >& objects) { 
    // Print the field names. 

    for(const string& name : objects.front()->GetFieldNames()) 
     cout << name << "\t"; 

    // ... code to print the actual data goes here ... 
} 

int main(int argc, char **argv) { 
    vector<shared_ptr<A> > myObjects; 
    myObjects.push_back(make_shared<B>("Box", "Storage container")); 
    myObjects.push_back(make_shared<B>("Glass", "Drink container")); 

    PrintTable (myObjects); 

    return 0; 
} 

我想問一下,如果它可以覆蓋一個靜態const成員,並延長它(我知道這聽起來有些矛盾),所以我可以添加字段靜態常量字段名,即東西如:

const vector<string> A::FieldNames = {"NAME"}; 
const vector<string> B::FieldNames = ClassA::FieldNames + {"DESC"}; // Obviously not possible! 

我也很樂意使用static const char* const FieldsConst[]而不是vector<string>

我看過this answerCRTP但我認爲它們不符合我的問題?

TIA :)

+0

您可以簡化代碼,以便更好地勾勒出你的問題嗎? – davestevens

+0

每個問題請提出一個問題。 –

+0

謝謝你的提示,我有(希望)簡化了一下代碼。 – iwbnwif

回答

0

好吧,我已經找到一種方法 - 它可以與LAMDA來完成。線索在this question

初始化B::FieldNames因爲我想,我應該使用:

const vector<string> B::FieldNames = [] 
    { vector<string> v = A::FieldNames; 
     v.push_back("DESC"); 
     return v; }();