C++ 如何动态创建方法来操作在运行时初始化的类对象
比如说,我有课C++ 如何动态创建方法来操作在运行时初始化的类对象,c++,class,object,cuda,C++,Class,Object,Cuda,比如说,我有课 class AddElement{ int a,b,c; } 使用设置/获取a、b、c的方法。。。我的问题绝对是一个逻辑问题——假设我实现如下加法: int Value=1; Value+=AddElement.get_a()+AddElement.get_b()+AddElement.get_b(); 现在假设我想做上面的事情,除了‘a,b,c’现在是数组,我做的不是‘加法’,而是标量加法。在运行时,有时我需要“a”,但不需要“b”或“c”,因此我可以重写为: Va
class AddElement{
int a,b,c;
}
使用设置/获取a、b、c的方法。。。我的问题绝对是一个逻辑问题——假设我实现如下加法:
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?(也就是说,如果我不打算使用一个巨大的数组,我不想对它进行malloc)
最后,我需要一个类,它有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
多亏了另一位用户,我研究了战略设计模式——这正是我用于解决这个问题的解决方案。我以前从未听说过这一点,最后我重新思考了一个已经解决的问题(花了一段时间才有人提及)。因此,解决方案是:
运行时确定算法=战略设计模式。元素的
std::vector
如何
至少可以说,问题规范有点不清楚,但我认为这对你来说是可行的
干杯,元素的
std::vector
怎么样
至少可以说,问题规范有点不清楚,但我认为这对你来说是可行的
干杯,您为您的类提供了一个方法
GetSumofActivieElements
,该方法可以按照名称执行。您可以将该类设置为虚拟类,并为每个场景创建子类,或者让该类以其他方式有效地管理内存。您为类提供了一个方法GetSumOfActiveElements
,该方法只需按照名称执行即可。您可以将该类设置为虚拟类,并为每个场景创建子类,或者让该类以其他方式有效地管理内存。这个粗略的代码大纲对您有用吗
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
}
这个粗略的代码大纲对你有用吗
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
}
像这样的怎么样
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;
向量值(3);
值[0]。第一个值=1;
值[0]。秒=假;
值[1]。第一个值=2;
值[1]。秒=真;
值[2]。第一个值=3;
值[2]。秒=假;
整数和=值[0]。第一个*值[0]。第二个+
值[1]。第一个*值[1]。第二个+
值[2]。第一个*值[2]。第二个;
您可能可以使用functor和
使其更清晰/可扩展
我不清楚为什么条件句是一件坏事——我想乘法的代价会更高。这是CUDA的局限性还是特质
如果您允许使用条件,您可以使您的
向量
成员成为一个封装了值和使用中标志的类,并根据需要使用过滤算法来执行聚合。这样的事情怎么样
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;
向量值(3);
值[0]。第一个值=1;
值[0]。秒=假;
值[1]。第一个值=2;
值[1]。秒=真;
值[2]。第一个值=3;
值[2]。秒=假;
整数和=值[0]。第一个*值[0]。第二个+
值[1]。第一个*值[1]。第二个+
值[2]。第一个*值[2]。第二个;
您可能可以使用functor和
使其更清晰/可扩展
我不清楚为什么条件句是一件坏事——我想乘法的代价会更高。这是CUDA的局限性还是特质
如果您允许使用条件,您可以使您的向量
成员成为一个封装了一个值和一个使用中标志的类,并根据需要使用过滤算法执行聚合。所以我想我得到了它-
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();
所以,基本上应该这样做!不,我可以使用调用:“apotIntertoanyFunction->AddValues()”来执行加法。实现可以由程序开始时的标志确定,然后我可以为需要满足的每个条件编写不同的类,然后让我的多态类继承基类的属性
很抱歉,如果我没有完全定义我的问题,或者声明很模糊-我真的不知道该怎么做,但我知道这是可能的。这样做对吗?有没有更有效的方法
感谢所有回应的人。当然,当x和y是数组时,我会在必要时动态分配x和y…所以我想我得到了