为了正确处理对象复制,经验法则是三规则.使用C++ 11,移动语义是一个东西,所以它是五条规则.然而,在这里和互联网上的讨论中,我也看到了对四条规则(一半)的引用,它是五条规则和复制交换习语的组合.
究竟是什么(四分之一)呢?需要实现哪些功能,每个功能的主体应该是什么样的?一半的功能是什么?与五法则相比,这种方法有任何缺点或警告吗?
这是一个类似于我当前代码的参考实现.如果这不正确,那么正确的实现会是什么样的?
//I understand that in this example, I could just use `std::unique_ptr`.
//Just assume it's a more complex resource.
#include <utility>
class Foo {
public:
//We must have a default constructor so we can swap during copy construction.
//It need not be useful, but it should be swappable and deconstructable.
//It can be private, if it's not truly a valid state for the object.
Foo() : resource(nullptr) {}
//Normal …Run Code Online (Sandbox Code Playgroud) c++ copy-constructor assignment-operator copy-and-swap c++11
假设我有一个看起来像这样的函数:
SomeObject copy_maybe(bool make_new, const SomeObject& def)
{
if (make_new)
return SomeObject();
else
return def;
}
Run Code Online (Sandbox Code Playgroud)
我称之为:
SomeObject obj;
obj = copy_maybe(true, obj);
Run Code Online (Sandbox Code Playgroud)
没有复制省略,这显然总会导致obj从临时创建的副本copy_maybe.然而,复制省略/ RVO,是有可能的是,副本将发生obj到obj?
更具体地,这些(或类似)条件下,是有可能在复制操作符(void operator=(SomeObject const &other)),其this和&other将是相同的,由于复制省略?
我在Ideone上创建了一个测试,它返回单独的地址,但我只是想确保这个行为是由规范定义的.
我有一个看起来像这样的课程:
class A
{
public:
void foo(int arg) { foo(arg, false); }
private:
void foo(int arg, bool flag) {}
};
Run Code Online (Sandbox Code Playgroud)
它是这样构建的,因为我希望foo'flag 参数仅在从外部调用时为 false A。我想私下继承它,但允许调用foo:
class B : private A
{
public:
using A::foo;
};
Run Code Online (Sandbox Code Playgroud)
但是,这失败了,因为 using 声明试图将 的所有重载foo带入范围,包括编译器正确拒绝的私有重载。
这不难解决,我也可以:
A::foo(int, bool)为 protected 或 publicA公开继承;只会foo继承的公共重载A::foo(int, bool)以便 using 声明不会尝试将其引入范围这是一个小型的私有项目,此外,该重载仅在内部调用A。所以解决这个问题在这里不是问题。(我只是要重命名私有重载。)
但感觉应该没有必要。为什么 using 声明试图将不可访问的方法带入范围?这个特殊情况是不是标准没有涵盖?除了我列出的方法之外,还有其他方法可以解决这个问题吗?