2010-10-25 44 views
1

我有一個類初始化類對象進行操作,說如何動態創建方法,在運行時

class AddElement{ 
    int a,b,c; 
} 

用的方法來設置/獲取A,B,C ......我的問題絕對是個邏輯問題 - 我說的addElement實現如下:

int Value=1; 
Value+=AddElement.get_a()+AddElement.get_b()+AddElement.get_b(); 

現在想象一下,我想要做的,除了上述「A,b,C」現在陣列和的,而不是「加」我做的標量增加。在運行時有時我需要「一個」,但不能「b」或「c」的,所以我可以改寫爲:

Value+=AddElement.get_a(); 

(當然,+ =過載來表示標量加法...和值是相同的大小a) - 其他時間,我可能只需要b或c被添加等...

有沒有辦法去選擇哪些元素,a,b,c,我想要初始化並在以後在運行時使用? (即,如果我不打算使用它,我不想malloc一個巨大的數組)。

最後我需要一個具有a,b,c的類,然後可以對a,b或c的任意組合進行操作的類 - 讓用戶在運行時定義他們需要的方法(通過某種標誌或配置文件)。

目前我做了以下內容:

Value+=AddElement.get_a()*FlagA+AddElement.get_b()*FlagB+AddElement.get_c()*FlagC; 

其中FLAGA = 1,如果你想用「A」中添加或0,如果你不希望它被包含(同爲FlagB和FlagC)。如果數組'a'非常大,這是昂貴的。

我可能只是不夠努力,但這個問題一直困擾着我。如果你需要我更好地定義這個問題,我會盡力,但我相信這足以讓我的觀點得到解決。

編輯2 我還忘了補充一點,另外的實施過程中,我可以不使用任何條件語句(這會在CUDA內核使用,我不能有任何線程diverngance - 我希望避免提及CUDA,因爲這完全是一個C++的問題)

編輯3 我相信什麼,我需要做的就是使用虛擬功能。我想以相同的方式調用函數,除非它執行特定於案例的功能。

編輯4 如果有人拍了一下我的解決方案,我將不勝感激 - 也許它太「異國情調」,有一個更簡單的實現同樣的目的方法。感謝所有的建議!

編輯5 感謝其他用戶,我查看了戰略設計模式 - 這正是我用於解決此問題的解決方案。之前我從來沒有聽說過這個消息,最終反思了一個已經完成的問題(花了一段時間讓某個人提到它)。所以解決方案: 在運行時確定算法=戰略設計模式。

+1

答案真的取決於您是否期望在將來會超過三個元素 - 即,如果您需要可擴展的解決方案或最佳的最快解決方案。另外,你的代碼有很多方面我不明白 - malloc?爲什麼你會用C++中的new來使用malloc?和(a)一樣?大多數C++用戶希望看到get_a()或類似的東西。 – Puppy 2010-10-25 14:59:25

+0

對於malloc感到抱歉,正如我所提到的,我正在使用CUDA(這是基於C的...),並且通常陣列在CPU和GPU之間進行復制時需要使用malloc。所以我想我說的是我需要它被優化和擴展......是的,會有比a,b和c更多的元素,但是我在將來我知道我不會去需要所有a,b,c,d ... n - 通常我可能只需要1或2個這些元素,但我不希望每次都重新編譯這些特定情況。 – Marm0t 2010-10-25 15:04:49

+0

您正在阻止我們提供一些信息,這些信息對於幫助您解決問題至關重要。主要的問題是你不能使用條件,這意味着你不能循環。但是你確實有一個總結數組的機制,可能是一個彙編指令集。我相信你需要使用相同的機制來解決這個問題,但不知道沒有更多的信息我可以幫忙。 – yonilevy 2010-10-25 15:42:31

回答

2

您提供您的類的方法GetSumOfActiveElements,不只是名字說什麼。你可以讓這個類變爲虛擬的併爲每個場景創建子類,或者讓這個類以其他方式有效地管理內存。

+0

這看起來像是在正確的軌道上,但我如何區分「活動元素」是什麼?我需要創建一些具有元素'isactive = true/false',然後是另一個元素int'a'的結構嗎?這又會涉及某些我試圖避免的條件。 – Marm0t 2010-10-25 14:56:59

+0

如果你打算總是使用全長列表,那麼你需要一些測試來消除你不想要的東西。用'mult by 1/0'代替'if'以避免條件工作,但我不清楚它是否更好 - 可能在CUDA上這是首選。 – 2010-10-25 15:34:06

+0

@Steve,我仍然需要測試哪個更快,發散或使用掩碼。 CUDA討厭分歧,所以我有一種感覺,我正在做的遮罩會更快。我會發佈一個關於它的話題......我自己和其他一些研究人員對這些影響感興趣。 – Marm0t 2010-10-26 13:01:42

0

元素的std::vector怎麼樣?

問題規格有點不清楚,至少可以說,但我認爲這將適用於你。

乾杯&心連心,

+0

我想要的代碼只執行'a','b'或'c'的任何組合,其中值爲+ = a + b + c如果a,b,c是需要的。如果不需要a,那麼我需要值+ = b + c,如果b不是必需的值+ = a + c等等......但我想定義這個沒有條件語句。感謝您的回覆 – Marm0t 2010-10-25 14:50:54

1

這是粗略的代碼大綱嗎?

struct S{ 
    int getx() {return 0;} 
    int gety() {return 0;} 
    int getz() {return 0;} 
}; 

int main(){ 
    int (S::*p[3])(); // allocate as per need 
    p[0] = &S::getx; // populate as per need at run time 
    p[1] = &S::gety; 
    p[2] = 0; 

    int val = 1; 
    S obj; 

    int nCount = 0; 

    while(p[nCount] != 0) 
     val += (obj.*(p[nCount++]))(); 
} 

編輯2:@Steve Townsend:沒錯。我錯過了有條件的東西。

這個怎麼樣。

struct S{ 
    int getx() {return 0;} 
    int gety() {return 0;} 
    int getz() {return 0;} 
    S(){} 
    S(S &obj, int (S::*p)()){ 
     val += (obj.*p)(); 
    } 
    static int val; 
}; 

int S::val = 0; 

int main(){ 
    S obj; 
    S buf[] = {S(obj, &S::getx), S(obj, &S::gety)}; // the magic happens here in 
                 // the constructor 
} 
+0

不是'有條件的嗎? – 2010-10-25 15:31:42

+0

它的相似,但我不能做一個循環(哎呀抱歉忘了說也是) - 我想我可能已經知道了,但:) – Marm0t 2010-10-25 15:32:18

+0

@Steve Townsend:哎呀!我錯過了有條件的東西。如何編輯2? – Chubsdad 2010-10-25 15:46:16

1

什麼這樣的事情?

vector<pair<int, bool>> values(3); 
values[0].first = 1; 
values[0].second = false; 

values[1].first = 2; 
values[1].second = true; 

values[2].first = 3; 
values[2].second = false; 

int sum = values[0].first * values[0].second + 
      values[1].first * values[1].second + 
      values[2].first * values[2].second; 

你可以使用仿函數和<algorithm>可能使這種清潔/可擴展性。

我不清楚爲什麼條件是一件壞事 - 我認爲乘法會更昂貴。這是CUDA限制還是特性?

如果您允許使用條件,您可以使您的vector成員成爲封裝值和使用中標誌的類,並使用過濾算法根據需要執行聚合。

+0

CUDA中的條件通常是不好的,如果它導致線程分歧(在我的情況下它會)。您發佈的案例與我現在實施的案例非常相似 - 由於CUDA API的限制,我無法使用vector class(我可能對此有錯)。 – Marm0t 2010-10-25 15:29:22

+0

@ Marm0t - 聽起來像CUDA的限制排除更優雅的解決方案,然後。祝你好運。 – 2010-10-25 15:32:00

1

所以我覺得我得到了它 -

struct S{ 
    int x,y; 
    bool needx,needy; 
}; 

class AnyFunction { 
    protected: 
     S Vals; 
     int TotalValue; 
    public: 
     virtual void SetValues(void) =0; 
     virtual void AddValues(void) =0; 
} 

class ImplementationFunc1 : public AnyFunction { 
    public: 
    void SetValues(S * Vals) { S.x=Vals->xval; } 
    void AddValues(void){ TotalValue+=Vals->x; } 
} 

class ImplementationFunc2 : public AnyFunction { 
    public: 
    void SetValues(S * Vals) {S.x=Vals->xval;S.y=Vals->yval;} 
    void AddValues(void){ TotalValue+=(Vals->x+Vals->y); } 
} 

int main(){ 
S SVals; 
AnyFunction * APointerToAnyFunction; 
// read a file that says if we need either x or y 
SVals.needx=true; // (i.e. read from file) 
SVals.needy=false; // (read from file) 

if(Svals.needx){ 
    SVals.x=Xfromfile; 
    if (Svals.needy){ 
     ImplementationFunc2 Imp1; 
     SVals.y=yfromfile; 
     APointerToAnyFunction=&Imp1; 
    } 
    else{ 
     ImplementationFunc1 Imp2; 
     APointerToAnyFunction=&Imp2; 
    } 
} 
... 
// blah set some values 
... 

// So now I can call the function the same way (i.e. the call is always the same, no matter what kind of addition it needs to do), but I have all 
// the logic for the conditions done _outside_ the addition 
APointerToAnyFunction->AddValues(); 

所以應該基本上做到這一點!不,我可以使用該調用:「APointerToAnyFunction-> AddValues()」執行添加。實現可以由程序開始時的標誌確定,然後我可以爲每個需要滿足的條件編寫不同的類,然後讓我的多態類繼承基類的屬性。

對不起,如果我沒有完全定義我的問題,或聲明是模糊的 - 我真的不知道如何做我正在解釋,但知道這是可能的。這是否正確?有沒有更高效的方法?

感謝所有回覆。當然,當x和y是數組時,我會在需要時動態分配x和y ...

+0

我會讓你們確定這是否是一個適當的解決方案,對不起,我不能更好地解釋。我使用它來調用取決於邊界條件(表示爲數組)的CUDA內核。我需要對我的BC進行靈活處理,所以我必須完成所有可能的組合(或者至少是最常見的組合)。如果我創建了一個.so,我應該避免在運行時與不必要的類鏈接 - 或者編譯器不能確定它是否真的需要所有的類直到執行(我猜是後者)? – Marm0t 2010-10-26 01:08:09

+0

這與策略設計模式類似,我並沒有故意提出這一點,因爲如果我們有三個以上例如a,b,c,d,e,f等等,基類'X'將無法處理它,我提出的解決方案更加通用,但無論如何, – Chubsdad 2010-10-26 04:05:19

+0

啊,是的,我只是看了一下策略設計模式!應該可能需要更多的課程來編程和算法(aero BS對編程來說很沒用......) – Marm0t 2010-10-27 15:56:23