我们的C++教授提到,使用operator->的结果作为另一个operator->的输入被认为是不好的风格。
因此,与其写:
return edge->terminal->outgoing_edges[0];
他更喜欢:
Node* terminal = edge->terminal;
return terminal->outgoing_edges[0];
发布于 2012-07-10 21:15:08
你应该问问你的教授,为什么他认为这是一种糟糕的风格。我不这么认为,但是我认为他在终端声明中省略const是一种糟糕的风格。
对于像这样的单个代码片段来说,它的风格可能还不错。但是,请考虑以下内容:
void somefunc(Edge *edge)
{
if (edge->terminal->outgoing_edges.size() > 5)
{
edge->terminal->outgoing_edges.rezize(10);
edge->terminal->counter = 5;
}
++edge->terminal->another_value;
}
这开始变得笨拙起来--它很难读,也很难写(我在输入的时候犯了大约10个打字错误)。它需要对这两个类的运算符->进行大量计算。如果运算符是微不足道的,但如果运算符做了任何令人兴奋的事情,那么它最终将做大量的工作。
所以有两个可能的答案:
而像这样的单个代码片段,您无法避免额外的行。在上面这样的情况下,它将导致更少的输入。
发布于 2012-07-10 21:11:43
原因有很多。
Law of Demeter给出了一个结构原因(请注意,您的C++教授的代码仍然违反了这一点!)。在您的示例中,edge
必须了解terminal
和outgoing_edges
。这使得它紧密耦合在一起。
作为替代方案
class Edge {
private:
Node* terminal;
public:
Edges* outgoing_edges() {
return terminal->outgoing_edges;
}
}
现在,您可以在一个地方更改outgoing_edges
的实现,而不必到处更改。老实说,对于像图这样的数据结构(它是紧密耦合的,边和节点不能彼此逃脱),我并不真的相信这一点。在我的书中,这将是过于抽象的。
还有空引用的问题,在表达式a->b->c
中,如果b
为空怎么办?
发布于 2012-07-10 21:17:16
嗯,我不能肯定你的教授的意思,但我有一些想法。
首先,像这样的代码可能是“不那么明显的”:
someObjectPointer->foo()->bar()->foobar()
你不能真正说出foo()
的结果是什么,因此你也不能真正说出bar()
被调用的是什么。这是同一个物体吗?或者它可能是一个正在创建的临时对象?或者可能是别的原因?
另一件事是如果你必须重复你的代码。考虑下面这样的例子:
complexObject.somePart.someSubObject.sections[i].doSomething();
complexObject.somePart.someSubObject.sections[i].doSomethingElse();
complexObject.somePart.someSubObject.sections[i].doSomethingAgain();
complexObject.somePart.someSubObject.sections[i].andAgain();
将其与以下内容进行比较:
section * sectionPtr = complexObject.somePart.someSubObject.sections[i];
sectionPtr->doSomething();
sectionPtr->doSomethingElse();
sectionPtr->doSomethingAgain();
sectionPtr->andAgain();
您可以看到第二个示例不仅更短,而且更容易阅读。
有时函数链更简单,因为您不需要关心它们返回的内容:
resultClass res = foo()->bar()->foobar()
vs
classA * a = foo();
classB * b = a->bar();
classC * c = b->foobar();
另一件事是调试。调试长的函数调用链是非常困难的,因为您根本不能理解它们中的哪一个会导致错误。在这种情况下,打破链条很有帮助,更不用说你还可以做一些额外的检查,比如
classA * a = foo();
classB * b;
classC * c;
if(a)
b = a->bar();
if(b)
c = b->foobar();
所以,总的来说,你不能说它是一种“坏”或“好”的风格。你必须先考虑你的情况。
https://stackoverflow.com/questions/11413939
复制相似问题