
想问一下 https://stackoverflow.com/questions/3279543/what-is-the-copy-and-swap-idiom/3279550#3279550 这个链接里的这个下面这段 public: friend 是怎么理解的呢? po 主尽力看了原回答给的链接,有些没有看懂。
class dumb_array { public: friend void swap(dumb_array& first, dumb_array& second) // nothrow { // enable ADL (not necessary in our case, but good practice) using std::swap; // by swapping the members of two objects, // the two objects are effectively swapped swap(first.mSize, second.mSize); swap(first.mArray, second.mArray); } }; 1 ysc3839 Sep 12, 2019 via Android 因为 mSize 和 mArray 是 private 的,所以需要声明成 friend 才能访问。 |
3 Tony042 Sep 13, 2019 同意楼上的,另外 friend 声明写在 public 上面吧,还有 declaration 和 definition 最好分开写,写在一起很乱 |
4 alanlian OP @Tony042 emm 这个只是一个小 sample,是我给的链接里的回答者拿来说明 copy-and-swap idiom 这个问题的,他好像是特意把 friend 写在那个位置的?可以看一下我给的链接 |
8 secondwtq Sep 13, 2019 friend 好像是只能写在这吧 ... 这里 swap 是个成员函数,成员函数是可以不加 friend 访问自己的 private 成员的 之前好像没见过这么写 copy-and-swap idiom 的(不过 C++11 之后好像不用这个 idiom 也可以了 |
9 secondwtq Sep 13, 2019 啊等等我好像搞混了,无视掉 #8 的评论吧 ... 我再看看 |
10 cyyzero Sep 13, 2019 via Android 没有 friend 就是成员函数了啊 |
11 shiltian Sep 13, 2019 那段代码应该这样写才是直观的: class dumb_array { public: friend void swap(dumb_array& first, dumb_array& second); }; void swap(dumb_array& first, dumb_array& second) { ... } 类里面的那个函数是“声明”,下面的那一段才是真正的“定义”。因为在函数的实现里面用到了类的私有成员,因此就必须得将这个函数在类里面声明成 friend 才可以。 |
13 alanlian OP @ysc3839 https://paste.ubuntu.com/p/C9bNY8XBJV/ 大约是这样的,你看有什么问题麽? |
15 alanlian OP @tianshilei1992 但是为什么不可以直接作为一个成员函数呢? |
16 ysc3839 Sep 13, 2019 via Android @alanlian 因为没有在类外部调用 swap,所以没问题吧。 代码中给出的用法是 std::swap 这样单独一个函数的 https://en.cppreference.com/w/cpp/algorithm/swap 你不写 friend 的话就变成类中的函数了,要使用的话会变成 a.swap(a, b) 这种样子。 |
17 nost Sep 13, 2019 不加 friend 是可以编译成功的,这样的 swap 是类的一个成员函数,对于 operator=这样的操作也是没有问题的。 但是对于如果在类的外部调写这样的代码。比如在 main 函数中写:dumb_array a, b; std::swap(a, b);那么在 c++11 中是 c=move(a),a = move(b), b = move(c)这样的操作,因为 dumb_array 没有写移动构造和移动赋值函数,就导致会调用拷贝构造函数。 这样导致的问题就是,swap 本来可以直接将类内的数组指针值进行替换,却多构造了一个临时数组,来进行换值操作。 当把 swap()写成 friend 之后,swap 就成了 std::swap()的一个重载函数,当在 main 中进行 std::swap(a,b)调用的时候,调用到的就是作为 friend 函数的 swap,也就是 std::swap()的定制版。这样就是直接将类内的指针进行交换,而不用进行额外的拷贝构造函数的调用。 不知这样,讲明白了没有。 |
21 secondwtq Sep 13, 2019 via iPad 这个不是重载的 std::swap,这个新函数应该是通过 ADL 被找到的 |
22 alanlian OP @secondwtq https://stackoverflow.com/questions/11562/how-to-overload-stdswap 这个链接里的这个巨巨也是用的 overload 这个词呢?您看下 |
23 secondwtq Sep 13, 2019 @alanlian 意思类似于: Q:传输大文件用什么服务最吼? A:顺丰快递 你感受一下 标准对 overload 的定义:“When two or more different declarations are specified for a single name **in the same scope**, that name is said to be overloaded.” technically,你在使用 swap 的时候用了 overload resolution 的机制,overload resolution 在决定 candidate set 的时候会考虑 scope 和 ADL。不过 overload resolution 和 overloading 是两回事 |
25 secondwtq Sep 13, 2019 其实应该说,你正确调用 swap 的时候,把 std::swap 重载了 另外 C++20 之前调 std::swap 应该是不会调到你的 swap 去的 |
26 baixiangcpp Sep 13, 2019 《 EFFective C++》肯定没好好看 |
27 baixiangcpp Sep 13, 2019 接上条,没写完就发了) 里边专门有个条款,就讲了 swap,虽然《 C++ primer 》也提过一嘴,但是一笔带过了..... |