2012-03-19 55 views
1

我有一堆屬性可以是NOP或有一個狀態。對於他們的要求是在用戶不需要該屬性時仍然沒有任何大小,但仍包含某些方法。舉個例子:在編譯時編寫成員

struct AttributeATag {}; 

/* The template used when AttributeATag is not specified */ 
template <typename T> 
class AttributeA 
{ 
public: 
    void foo(uint32_t v) 
    { 
     // Nop, do nothing 
    } 

    enum 
    { 
     HasAttributeA = false 
    }; 
}; 

/* The template specialization used when AttributeATag is specified */ 
template <> 
class AttributeA<AttributeATag> 
{ 
public: 
    void foo(uint32_t v) 
    { 
     this->omgVariable = v; 
    } 

    enum 
    { 
     HasAttributeA = true 
    }; 
protected: 
    int omgVariable; 
}; 

template <typename ATag> 
class MyUberClass : public AttributeA<ATag> 
{ 
    // This class now has omgVariable or not, depending on ATag and it 
    // has either a NOP method or one which actually does something 
    void doSomething() 
    { 
     if (AttributeA<ATag>::HasAttributeA) 
     { 
      /* ... */ 
     } 
    } 
}; 

這工作,但現在有一個問題:NOP的大小屬性,而被空類,不爲0,這意味着100個空屬性添加了大量的未使用空間MyUberClass。

有沒有辦法避免這種情況,並添加/刪除基於模板參數的成員變量?


編輯:

據我所知,空的類沒有大小的0。當我嘗試以下方法,我得到的sizeof(B)== 4.

template <typename T> 
class A 
{ 

}; 

class B : public A<int>, public A<double>, public A<char>, public A<long>, public A<bool> 
{ 

}; 
+0

'AttributeA '只有在'ATag = AttributeTag'時纔會有大小。其餘案例將僅爲空課。這個「100」號碼從哪裏來?我沒有看到任何問題。請清楚你的問題。 – iammilind 2012-03-19 03:30:39

+0

100只是誇大了這個問題。 – Howie 2012-03-19 03:37:15

回答

0

由於您使用AttributeA作爲基類,幾乎每個編譯器都會使用「空基優化」來確保空基類在子類中不使用空格,即使基類的大小類非零。我不相信你在這裏有問題。每個類(基類/子類)至少需要一個字節(如果編譯器填充所有內容,可能需要四個字節),但空基(幾乎在所有情況下)都不會增加子類的大小本來已經是了。

+0

我剛剛使用MSVC 10運行我的編輯(請參閱我的文章),sizeof(B)在編譯時仍然返回4。你確定這個進行了優化嗎? – Howie 2012-03-19 03:39:58

+0

我認爲這是我編譯器的問題。它應該應用空基類優化,但由於某種原因,MSVC10只爲第一個基類做了這些工作,併爲其他類增加了1個字節。 – Howie 2012-03-19 13:49:40

0

在這個測試:

#include <iostream> 
struct g{}; 
int main() 
{ 
    std::cout << sizeof(g) << std::endl; 
} 

海合會我得到一個大小爲1,這可能是因爲你還需要能夠有一個指向它無論作爲不管它是否保持狀態。

我不瘦,沒有訴諸於某個課程之外的東西,

+0

除了班級以外的東西?那會是什麼? – Howie 2012-03-19 03:36:24

+0

@HowieHowitzer恐怕我的答案結束了。也許是一個不同的設計,但這並不是那麼有用,我很抱歉。 – 111111 2012-03-19 03:45:04

0

無論任何數量的(空)類是否被繼承,一個空類的最小大小爲1個字節。
在你的例子中,class B將有最小實現定義的大小,(看起來你的情況下爲4字節),無論你是從其他類繼承還是不繼承。

這是需要的,以便任何空的class對象可以有一個唯一的地址。沒有什麼可以做的。

+0

這與sizeof(A )== 1不一樣。這意味着,使用我的編譯器(MSVC10),空類的大小爲1個字節,所以對於sizeof(B)== 4,顯然空類的確會增加到B的大小。 – Howie 2012-03-19 04:28:03