在方法中返回静态变量是个坏主意
Is returning static variables in methods a bad idea?
我到处找了找,似乎找不到问题的答案。我正在做一个项目,在这个项目中,我必须为向量和多项式之间的运算重新定义一些运算符(+
、-
、*
等)。据我所知,如果我们只是调用运算符(即vect1+vect2;
而不是vect1 += vect2;
)而不将结果放在任何位置,那么这些运算符应该返回对象的副本,以免直接修改它们。
现在,我已经看到了使用静态变量是一种糟糕的做法,但当一个方法需要返回结果的副本而不是修改对象时,我该如何避免这样做呢?
这里和这里的问题并没有真正帮助,因为它们没有解决我的特定问题。
下面是我的意思的一个例子:
template <class elem>
Vect_variable<elem>& Vect_variable<elem>::operator+(const Vect_variable& operand)
{
if (taille >= operand.taille)
{
static Vect_variable<elem> temp_v;
temp_v = *this;
for (std::size_t i = 0; i<operand.taille; i++)
{
temp_v[i] += operand.vecteur[i];
}
return temp_v;
}
else
{
static Vect_variable<elem> temp_v;
temp_v = operand;
for(std::size_t i = 0; i<taille; i++)
{
temp_v[i] += vecteur[i];
}
return temp_v;
}
}
在这种情况下,您可以看到我正在为所使用的临时变量创建静态Vect_variable
。有别的办法吗?
是。不要将变量设为static
。这样,每个对函数的调用都会得到自己的新变量,然后返回。
此外,它是自动的(在堆栈上)而不是静态的,您可以一次性声明变量并初始化它。
我没有注意到你正在返回向量的引用。不要那样做。按值返回。
template <class elem>
Vect_variable<elem> Vect_variable<elem>::operator+(const Vect_variable& operand)
{
if (taille >= operand.taille)
{
Vect_variable<elem> temp_v = *this;
for (std::size_t i = 0; i<operand.taille; i++)
{
temp_v[i] += operand.vecteur[i];
}
return temp_v;
}
else
{
Vect_variable<elem> temp_v = operand;
for(std::size_t i = 0; i<taille; i++)
{
temp_v[i] += vecteur[i];
}
return temp_v;
}
}
接下来要做的是注意,您在两个分支中执行的几乎是相同的操作。这只是取决于哪条尾巴更短。所以使用一对指针:
{
decltype(this) one, two;
if (taille >= operand.taille)
{
one = this;
two = &operand;
}
else
{
one = &operand;
two = this;
}
Vect_variable<elem> temp_v = *one;
for (std::size_t i = 0; i<two->taille; i++)
{
temp_v[i] += two->vecteur[i];
}
return temp_v;
}
最后的评论是,通常最好先写operator +=
,然后把operator +
写成一个带有签名的非成员二进制函数:
TYPE operator +(TYPE lhs, const TYPE& rhs)
{
lhs += rhs;
return lhs;
}
请注意,lhs
由值获取(因此您已经有了自己的副本)。非成员函数的优点是,如果有任何到TYPE
的转换函数,它们将在左手边和右手边对称操作。
稳健而简单的方法是按值返回一个(非静态)局部变量。在某些情况下,这也是有效的方法。
如果您非常关心效率,那么对于两个输入中的一个是右值的情况,您需要一个替代执行路径。在这种情况下,您根本不需要局部变量。相反,您希望通过右值引用获取输入,修改它并通过右值参考返回它。
为了避免重复代码过多,您可能需要定义一个operator+=
,并将实际工作放在该方法中,并让operator+
的所有版本将工作委托给operator+=
在某些情况下,通过引用返回static
变量比以上所有情况都更有效。但这种情况并不多,而且充满了足够多的危险,你不应该做出这样的选择。
看到您对前面的答案所做的评论后:您是正确的,通过引用返回static
避免了从虚拟函数的重写中获得多态返回的大问题。但它这样做是以制造自身问题为代价的。举一个简单的例子,假设有人使用您的+
来计算A+(B+C)
。不要问为什么他们放了那些不合适的()
。只是意识到他们没有办法知道他们不应该。因此,您的操作符将B
复制到一个静态并将C
添加到该静态,然后将A
复制到同一个静态,并将该静态添加到其中并返回2A
。虽然这个例子是人为设计的,但如果+
返回对静态的引用,它只是可能会出现严重错误的许多事情之一。
- 有没有什么方法可以使用一个函数中定义的常量变量,也可以由c++中同一程序中的其他函数使用
- 枚举环境变量的惯用C++14/C++17方法
- 绑定派生类方法C++从实例范围之外的分隔 std::function 变量调用
- 是否可以依赖函数范围的静态变量来执行程序关闭期间调用的方法?
- 从私有成员变量的成员方法返回unique_ptr
- 在派生类中使用基类的私有成员变量的最佳方法
- 打印所有继承的类成员变量和方法
- C++方法中的引用变量
- Visual C++: MSVC vs. GCC+CLANG: 处理 lambda 捕获类成员变量,正确的方法是什么?
- 有没有一种通用的方法来实现不变量
- 有没有将变量名称转换为双指针的简短方法?
- C++:将向量传递到构造函数以创建成员变量的最佳方法?
- C++中变量混叠的最佳方法
- 比较C++变量的最有效方法
- 使用类在C++中存储和列出变量/方法是否是一种好的做法
- 存储变量的更有效方法是什么?
- 对具有相同方法的不同类使用一个变量
- 如何使用另一个变量访问对象的变量/方法
- C++,静态局部变量(方法)与全局(文件)变量有什么区别
- Awesomium允许我在JS中调用/使用c++变量/方法吗?