Ale*_*tof 11 c++ pure-virtual move-semantics c++11
在C++ 11中,我们在某些情况下被指导为按值传递对象,在其他情况下通过const-reference传递对象.但是,本指南取决于方法的实现,而不仅仅取决于其接口和客户的预期用途.
当我编写一个接口时,我不知道它将如何实现.写方法签名有一个很好的经验法则吗?例如 - 在下面的代码片段中,我应该使用Bar1
或Bar2
?
class IFoo
{
public:
virtual void Bar1(std::string s) = 0;
virtual void Bar2(const std::string& s) = 0;
};
Run Code Online (Sandbox Code Playgroud)
如果您同意正确的签名取决于实施,您可以在此处停止阅读.这是一个例子,说明我相信的原因.
在以下示例中,我们应该按值传递字符串:
class Foo
{
std::string bar;
Foo(std::string byValue)
: bar(std::move(byValue))
{
}
};
Run Code Online (Sandbox Code Playgroud)
现在我们可以在所有情况下以有效的方式实例化Foo:
Foo foo1("Hello world"); // create once, move once
Foo foo2(s); // the programmer wants to copy s. One copy and one move
Foo foo3(std::move(t)); // the programmer does not need t anymore. No copy at all
Run Code Online (Sandbox Code Playgroud)
在其他情况下,我们更喜欢通过const引用传递对象.例如,在下面的例子中,我们永远不想复制/存储参数,只需使用它的方法:
void DoStuff(const std::string& byRef)
{
std::cout << byRef.length() << std::endl;
}
Run Code Online (Sandbox Code Playgroud)
上述方法的所有可能用法都已尽可能高效.
更新
我相信我忘了展示const-reference替代方案的问题.如果以上Foo
方式实现了上述类:
class Foo
{
std::string bar;
Foo(const std::string& byRef)
: bar(byRef)
{
}
};
Run Code Online (Sandbox Code Playgroud)
然后我们会得到以下结果:
Foo foo1("Hello world"); // Here we would have one more copy of the string. It is less efficient.
Foo foo2(s); // One copy, like before
Foo foo3(std::move(t)); // Irrelevant here.
Run Code Online (Sandbox Code Playgroud)
亚历克斯.
这里不存在“万有理论”。你没看错,有问题。我记得不久前我自己也遇到过这个问题。
我的结论从这里开始:
如果您的客户是开发人员,这项工作就会困难得多。不仅更难,而且没有明确的指导方针。伟大的框架设计师之所以享有盛誉,是因为他们碰巧承担了获得回报的风险。与此同时,在另一个宇宙中,他们的风险可能不会得到回报。这是因为,对一个框架的欣赏取决于其使用增长的方向,以及比应用程序领域更难推理的主观意见。
所以这个案子没有明确的答案。幸运的是,我认为您主要对这里的应用程序开发感兴趣。那么让我们继续讨论吧。
这造成了巨大的差异。因为我们应该更好地了解系统的发展方向,以及什么样的代码会变得有用。我们不是预言家,但与此同时,这种假设使我们能够更多地相信我们的直觉,这种直觉基于我们对需求的了解以及客户的需求(至少是我们能够理解的程度) )。
此时,我们仍然可以将其分为2种情况:
在某些情况下,在实现之前定义抽象是有益的,甚至是必要的。在这种情况下,人们必须认识到,在正确定义抽象之前,需要对问题进行更多研究。例如,域是同步的还是异步的?串行还是并行?高水平还是低水平?以及其他更具体的问题。
一些极端的敏捷者会让你相信你可以只编写一些代码并稍后修复它。然而,一旦现实来临,这种说法很容易被证伪。如果您从中找到希望,我鼓励您亲自测试并报告您是否有任何重大发现。我的个人经验以及我尝试过解决这个问题的想法表明,在大型项目中这种方法是非常有问题的。
本例的结论是,如果您确实需要提前定义抽象,那么您应该已经对实现有了很好的了解。你对它的想法越好,它真正成为正确抽象的机会就越大。
这是我的默认选择。这已经从很多方面说过了。“框架应该被提取”,“提取到你放弃”,甚至“约定优于配置”在概念上都有一些相似之处。
基本上,这意味着您根据需要实现所需的组件,但要密切关注正在发生的事情。这里的技巧是寻找机会以在开发和维护方面真正有益于您的方式进行抽象。
这通常是一个类,它可以做你想做的事,但更多。在这种情况下,您可以将交集抽象为更一般的情况。在整个开发过程中,您可以根据需要重复此过程。
重要的是不要陷入困境并仍然脚踏实地。我见过许多抽象尝试都出错了,除了阅读使用它的数千行代码之外,无法推理其名称并推断出其意图。例如,在我正在处理的当前代码库中,应该调用的类型Image
称为BinaryData
。整个代码都试图将其视为具体的(图像),同时也视为抽象的概念。
正如我总是提醒自己的那样,您可以拥有的最佳实践是驯服已知的最佳实践来适应您的问题,而不是相反。如果你做不到这一点,那么,也许这个问题很有趣,需要进一步的关注和一些原创的想法。
归档时间: |
|
查看次数: |
791 次 |
最近记录: |