2010-10-25 50 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