我有一节课:
class A
{
public:
//copy and move constructor,operator=
A func(const A& a,const A& b)
{
A c;
//do some stuff...
return c;
}
};当我以这种方式使用它时,它工作得很好:
A a;
A b;
A c=func(a,b);但问题是当我以这种方式使用它时:
A a;
A b;
a=func(a,b);它做了一些不必要的事情(做c,在我的类中调用构造函数是很费时的!)
我想知道,如果a等于传递给函数的变量之一,那么我就不做c,而是就地做一些事情。
经过一段时间的思考,我想出了一个解决方案:
class A
{
public:
//copy and move constructor and operator=
A func(const A& a,const A& b)
{
A c;
//do some stuff...
return c;
}
A func(const A& a,const A& b,bool inPlace)
{
if(!inPlace)
return func(a,b);
else
{
//const-cast a then do stuff on a
return a;
}
}
};现在,它可以很好地处理:
A a;
A b;
A c=func(a,b);
a=func(a,b,true);但它仍然不适用于:
A a;
A b;
b=func(a,b,true);因此,func还需要另一个重载。
但这似乎是个糟糕的设计。上这门课有什么更好的主意吗?
请注意,我不想这样做:
void func(const A& a,const A& b,A& result)(很抱歉,我找不到一个更好的题目:)
编辑
我的构造函数如下所示:
A(unsigned int SIZE)
{
// all of these are vectors and SIZE is about 1k
realData_.reserve(SIZE);
timePerUnit_.reserve(SIZE);
prob_.reserve(SIZE);
//....
// some math stuff for filling them
}发布于 2014-02-27 09:04:08
根据我对您的问题的理解,您想要编写一个A &func(const A& a,const A& b),它返回一个新构造的A,但作为优化,您希望修改a或b,而不是构造一个新的A,如果func的结果分配给a或b。
当您编写a = func(a, b)时,这就像a.operator=(func(a, b))。func将不知道它的返回值是如何使用的,operator=也不知道它的参数来自func。如果您想为这种特殊情况进行优化,您需要为它编写额外的函数。
您可以编写未经优化和优化的版本:
A &func(const A& a, const A& b) { A c; ...; return c; }
void func(A& a, const A& b) { modify a; }
void func(const A& a, A& b) { modify b;}
// In case func(a,b)==func(b,a) for const a and const b you can write:
void func(const A& a, A& b) { func(b, a); }或者您可以编写一个通用版本:
void func(const A& a, const A& b, A& result)
{
if(&result == &a)
optimized modify result;
else if(&result == &b)
optimized modify result;
else
unoptimized modify result;
}如果幸运的话,您甚至不需要区分泛型版本中的不同情况。但这取决于你所做的计算。
顺便说一句,如果你在看STL,你会发现他们在做类似的事情。将A替换为string,func替换为operator+,您将得到string operator+ (const string& lhs, const string& rhs);。此运算符将始终创建一个新对象,并返回该对象。为了对这种情况进行优化,str1 = str1 + str2;声明了一个额外的函数operator+=。这是您需要做的相同的事情-只是您的函数有名称func而不是运算符.。
发布于 2014-02-27 08:49:01
如果你绝对不想使用:
void func(const A& a, const A& b, A& result)然后,您可以通过为第三个参数而不是bool使用指针来避免单个重载,例如:
A func(const A& a, const A& b, const A* resultPlace = NULL)
{
if (resultPlace == &a) {
// Do in place stuff with a
return a;
}
else if (resultPlace == &b) {
// Do in place stuff with b
return b;
}
else {
A c;
// whatever
return c;
}
}当然,您可以这样称呼它:b = func(a, b, &b);
不知道你能不能做得比这更好,但我怀疑你能否做到你的问题标题具体要求。
https://stackoverflow.com/questions/22062478
复制相似问题