如何动态创建方法来操作在运行时初始化的类对象

发布于 2024-09-29 07:55:38 字数 1333 浏览 2 评论 0原文

我有一个类,比如说

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 ' 现在是数组,我不再进行“相加”,而是进行标量相加。在运行时有时我需要'a'但不需要'b'或'c',所以我可以重写为:(

Value+=AddElement.get_a();

当然+=被重载以表示标量加法......并且值是与 a 大小相同) - 其他时候我可能只需要添加 b 或 c 等...

有没有办法选择我想要初始化并稍后在运行时使用的元素 a、b、c? (即,如果我不打算使用它,我不想分配一个巨大的数组)。

最后,我需要一个具有 a、b、c 的类,然后是可以对 a、b 或 c 的任意组合进行操作的方法 - 让用户定义他们在运行时需要的方法(通过某种标志或配置)文件)。

目前我正在执行以下操作:

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

如果您想在加法中使用“a”,则 FlagA=1;如果您不想包含它,则为 0(FlagB 和 FlagC 相同)。如果数组“a”非常大,则成本高昂。

可能只是我想得不够仔细,但这个问题一直困扰着我。如果您需要我更好地定义问题,我会尝试,但我相信这足以表达我的观点。

编辑2 我还忘记补充一点,在执行添加过程中我不能使用任何条件(这将在 CUDA 内核中使用,并且我不能有任何线程分歧 - 我希望避免提及 CUDA,因为这是完全是一个 C++ 问题)

编辑 3 我相信我需要做的是使用虚函数。我想以相同的方式调用该函数,除了让它执行特定于案例的函数。

编辑4 如果有人看一下我的解决方案,我将不胜感激 - 也许它太“异国情调”,并且有一种更简单的方法可以实现相同的目的。感谢您的所有建议!

编辑5 感谢另一位用户,我查看了战略设计模式 - 这正是我用于解决此问题的解决方案。我以前从未听说过这一点,最终重新思考了一个已经完成的问题(花了一段时间才有人提到这件事)。所以解决办法: 在运行时确定算法=战略设计模式。

I have a class, say

class AddElement{
    int a,b,c;
}

With methods to set/get a,b,c... My question is definitely a logic question - say I implement AddElement as follows:

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

Now imagine I want to do the above except 'a,b,c' are now arrays, and instead of 'adding' I do scalar addition. At runtime sometimes I need 'a' but not 'b' or 'c', so I could rewrite as:

Value+=AddElement.get_a();

(Of course the += is overloaded to represent a scalar addition... and Value is the same size as a) - Other times I might only need b or c to be added etc...

Is there a way to go about selecting which elements, a,b,c, I want to initialize and later use at runtime? ( i.e. I don't want to malloc a huge array if I'm not going to use it).

In the end I need a class that has a,b,c and then methods that can operate on any combination of a,b, or c - having the user define what methods they need at runtime (via some kind of flag, or config file).

Currently I'm doing the following:

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

where FlagA=1 if you want to use 'a' in the addition or 0 if you don't want it to be included (The same for FlagB and FlagC). This is costly if the array 'a' is very large.

I'm probably just not thinking hard enough, but this problem has been bothering me. If you need me to better define the issue I will try, but I believe this is enough to get my point across.

Edit 2
I also forgot to add that I can't use any conditionals during the implementation of the addition (this is going to be used in a CUDA kernel and I can't have any thread diverngance - I was hoping to avoid mentioning CUDA since this is entirely a c++ question)

Edit 3
I believe what I need to do is use virtual functions. I want to call the function in the same manner, except have it execute a case specific function.

Edit 4
I would appreciate if someone took a look at my solution - maybe its too 'exotic' and there's a simpler method to accomplish the same end. Thanks for all the suggestions!

Edit 5
Thanks to another user I looked at the Strategic Design Pattern - and this is exactly the solution I used for this problem. I had never heard of that before and ended up rethinking a problem that has already been done (took a while for someone to mention something about it). So the solution:
Determine Algorithm at Runtime = Strategic Design Pattern.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

べ映画 2024-10-06 07:55:38

您为您的类提供了一个方法 GetSumOfActiveElements,该方法正如其名称所示。您可以使此类成为虚拟类并为每个场景创建子类,或者让该类以其他方式有效地管理内存。

You provide your class with a method GetSumOfActiveElements that does just what the name says. You can make this class virtual and create subclasses for each scenario, or have the class manage the memory efficiently in some other way.

避讳 2024-10-06 07:55:38

像这样的事怎么办?

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;

您可以使用函子和 使其更清晰/可扩展。

我不清楚为什么条件是一件坏事 - 我认为乘法会更昂贵。这是 CUDA 的限制还是特性?

如果允许条件,您可以使您的 vector 成员成为封装值和使用中标志的类,并使用过滤算法根据需要执行聚合。

What about something like this?

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;

You could probably make this cleaner/extensible using functors and <algorithm>.

It's not clear to me why conditionals are a bad thing - multiplication will be more expensive I would think. Is this a CUDA limitation or idiosyncracy?

If you allowed conditionals you could make your vector member a class that encapsulated a value and an in-use flag, and use filtering algorithms to perform aggregation as required.

小瓶盖 2024-10-06 07:55:38

这个粗略的代码大纲适合您吗?

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
}

Does this rough outline of code work for you?

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++]))();
}

EDIT 2: @Steve Townsend: That's right. I missed that conditional stuff.

How about this.

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
}
情深已缘浅 2024-10-06 07:55:38

所以我想我明白了 -

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......

So I think I got it -

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();

So that should basically do it! no I can use the call: "APointerToAnyFunction->AddValues()" To perform the addition. The implementation can be determined by flags at the beginning of the program, then I can write a different class for each condition that i need to satisfy, and then have my polymorphic class inherit the properties of the base class.

Sorry if I did not fully define my problem, or the statement was vague - I didn't really know exactly how to do what I was explaining, but knew it was possible. Is this the right way to go about this? Is there a more efficient way?

Thanks to all who responded. Of course when x and y are arrays, I dynamically allocate x and y when necessary...

我做我的改变 2024-10-06 07:55:38

元素的 std::vector 怎么样?

至少可以说,问题规范有点不清楚,但我认为这对您有用。

干杯&呵呵,,

How about a std::vector of elements?

Problem spec is a bit unclear, to say the least, but I think that would work for you.

Cheers & hth.,

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文