奇怪的C++语法?

7
这可能是一个愚蠢的问题,但我有一段代码有以下这行:

Solver *S, *STP = S = 
UseDummySolver ? createDummySolver() : new STPSolver(true);

我知道三元运算符,但等号有点让我困惑。能否有人给我解释一下?谢谢。

18
那是一种非常丑陋的同时给两个变量赋值的方法。(用火烧掉像这样的代码)。 - user7116
3
这段代码之所以糟糕,原因有很多。其中双重赋值只是其中之一,不使用 RAII 是另一个原因。 - Alexandre C.
是的...我甚至没有意识到那是合法的,而且我以前从未见过这样的情况! - steveha
5个回答

16

翻译后的结果是

Solver *S;
Solver *STP;
S = UseDummySolver ? createDummySolver() : new STPSolver(true);
STP = S;

虽然这样做是可行的,但是很不优美,我不建议在你的代码中这样做。

推荐的方法是这样编写代码(使用初始化而非赋值):

Solver *S = UseDummySolver ? createDummySolver() : new STPSolver(true);
Solver *STP = S;

2
为什么不使用初始化,而是用赋值? - Nawaz
@Nawaz他只是在向这个OP解释代码实际上是做什么的。 - NominSim
@Nawaz:我同意这样做更好。我只是想尽可能清楚地为OP写出来。 - houbysoft
@Nawaz:建议使用初始化而不是赋值。 - houbysoft
1
正如@Nawaz所说,这并不是“完全”相同,因为您正在分配STP而不是像OP的代码一样进行初始化。 - Kerrek SB

6
我建议这样做:
Solver *S = UseDummySolver ? createDummySolver() : new STPSolver(true);
Solver *STP = S;

这段内容简洁明了,整洁清晰。

此外,它使用了初始化而不是赋值。在任何可能的情况下,您应该优先选择初始化而非赋值。


1
因为你推荐使用初始化而不是赋值,我给了你一个+1的赞。 - houbysoft

5

您在观看链式赋值。

它与以下代码等效:

Solver *S;
Solver *STP;
S = UseDummySolver ? createDummySolver() : new STPSolver(true);
STP = S;

@sixlettervariables 对不起,已修正,C++ 不是我的强项。 - NominSim
时机是关键 :) +1 - houbysoft
1
@sixlettervariables,NominSim,我编辑了答案并放入了错误的解引用。对此我感到抱歉;原始代码让我感到困惑。这完全不是NominSim的错。 - steveha

2
三元运算符根据UseDummySolver布尔值返回一个结果,如果为真,则返回一个虚拟求解器,否则返回STPSolver()的新实例。这个返回值然后被存储在STPS中。

0
我更喜欢这个:
std::unique_ptr<Solver> S (  UseDummySolver
                                  ? createDummySolver()
                                  : new STPSolver(true)  );
Solver& STP = *S;

或者这样:

std::shared_ptr<Solver> S (  UseDummySolver
                                  ? createDummySolver()
                                  : new STPSolver(true)  );
std::shared_ptr<Solver> STP = S;

这段代码避免了一个问题:当对象离开作用域时,我们不需要决定在哪个指针上调用delete(或者干脆忘记调用delete的需要)。相反,我们只需等待变量离开作用域,那么Solver对象就会被自动删除。STP在第一种情况下无歧义地成为访问该对象的另一种方式,而在第二种情况下,它是该对象的独立 "共有者",两个指针都可以独立重新赋值。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接