2012-07-17 56 views
3

我正在研究一種情況,我希望有一個基類,它定義了一個靜態關聯數組和靜態函數,然後在它繼承的類中複製這個功能,但是與每個孩子類擁有自己的數組實例。看起來像子類只是繼承了父類的數組,而不是像我期望的那樣創建自己的靜態副本。下面是什麼我所希望實現超簡化的簡化版:D:繼承靜態變量,按類別區分?

class MyBase { 
    static string[string] dict; 
    static void attach(string key, string val) { 
     dict[key] = val; 
    } 
} 
class MySubA : MyBase { 
    // various unique member variables 
} 
class MySubB : MyBase { 
    // ... 
} 
void main() { 
    MySubA.attach("a", "a1"); 
    MySubB.attach("b", "b1"); 
    writefln("-:%s", MyBase.dict); 
    writefln("A:%s", MySubA.dict); 
    writefln("B:%s", MySubB.dict); 
} 

所需的輸出:

-:[] 
A:["a":"a1"] 
B:["b":"b1"] 

實際輸出:

-:["a":"a1", "b":"b1"] 
A:["a":"a1", "b":"b1"] 
B:["a":"a1", "b":"b1"] 

是否有辦法在這種情況下不要拋棄繼承,只需複製每個子類的相關代碼?分配給我正在使用的數組的實際代碼比上面列出的附加函數更復雜,因此我希望避免每次都複製它,或者在必要時手動分配給.dict。我想知道是否有解決方案涉及模板可能工作,但我似乎無法將它拼湊在一起。

回答

1

啊,看起來我只是偶然發現瞭解決方案。

class MyBase(T) { 
    static string[string] dict; 
    static void append(string key, string val) { 
     dict[key] = val; 
    } 
} 
class MySubA : MyBase!MySubA { 
    // various unique member variables 
} 
class MySubB : MyBase!MySubB { 
    // ... 
} 

確實是我想要的。根據快速禮儀搜索發佈自己的答案。

+2

就這麼你知道,'MySubA'和'MySubB'不以這種方式共享相同的基類。它們處於完全獨立的類層次結構中,因爲「MyBase!MySubA」和「MyBase!MySubB」是不同的類。同一個模板的不同實例是完全獨立的實體,彼此之間沒有任何關係。 – 2012-07-17 04:58:10

+2

如果實際上並不需要類層次結構(並且僅用於提供字典實現),那麼我會說模板mixin就是要走的路。 – 2012-07-18 10:03:26

+0

+1肯定。@ccjuju,如果你只是使用繼承來避免一點重複,那麼不要使用泛型。另一方面,如果這些類代表一個對象層次結構,那麼你發佈的解決方案就不會按照你的要求去做。 – Tim 2012-07-18 17:18:54

6

類中的靜態變量是該類的一部分,只是該類的一部分。在整個程序中都存在一個它的實例,不管該類的實例有多少已創建,或者有多少類已經從中派生。除了正常成員變量的繼承之外,沒有任何靜態成員變量的繼承。如果派生類是公共的或受保護的,它們可以訪問基本的變量,但它們不會獲得它們自己的副本。 Nothing被複制到派生類的鏈中。成員變量存在於它們聲明的類中,派生類可能有權訪問它們,但派生類不能獲得它們自己的副本。

因此,通過將dict放在MyBase中,無論派生類的作用如何,您都可以爲整個程序創建一個。如果你想讓每個派生類都有自己的副本,那麼他們每個人都必須聲明自己的副本。

現在,您可以通過模板mixin或字符串mixin最小化代碼重複,但是您仍然必須將其混合到每個派生類中。例如,你可以做到這一點

import std.stdio; 

mixin template Dict() 
{ 
    static string[string] dict; 
    static void attach(string key, string val) 
    { 
     dict[key] = val; 
    } 
} 

class MyBase 
{ 
    mixin Dict; 
} 

class MySubA : MyBase 
{ 
    mixin Dict; 
    // various unique member variables 
} 

class MySubB : MyBase 
{ 
    mixin Dict; 
    // ... 
} 

void main() 
{ 
    MySubA.attach("a", "a1"); 
    MySubB.attach("b", "b1"); 
    writefln("-:%s", MyBase.dict); 
    writefln("A:%s", MySubA.dict); 
    writefln("B:%s", MySubB.dict); 
} 
0

如果您不需要層次:

import std.stdio; 

mixin template Dict() 
{ 
    static string[string] dict; 
    static void attach(string key, string val) 
    { 
     dict[key] = val; 
    } 
} 

class MySubA 
{ 
    mixin Dict; 
} 

class MySubB 
{ 
    mixin Dict; 
} 

void main() 
{ 
    MySubA.attach("a", "a1"); 
    MySubB.attach("b", "b1"); 
    writefln("A:%s", MySubA.dict); 
    writefln("B:%s", MySubB.dict); 
} 

我認爲這是比這個模板繼承一個更好的解決方案。