我曾经认为,遵循最佳实践时,C ++的对象模型是非常强大的。 就在几分钟前,我意识到我以前没有过。 考虑这个代码: class Foo { std::set<size_t> set; std::vector<std::set<size_t>::iterator> vector; // … // (assume every method ensures p always points to a valid element of s) }; 我已经写了这样的代码。 直到今天,我还没有看到它的问题。 但是,再想一想,我意识到这个class很破碎: 它的复制构造函数和复制分配复制 vector 的迭代器 ,这意味着它们仍然指向旧 set ! 毕竟新的不是真的! 换句话说, 即使这个类没有pipe理任何资源(无RAII) , 我也必须手动实现copy-constructor ! 这让我感到惊讶。 我从来没有遇到过这个问题,我不知道有什么优雅的方法来解决它。 再想一想,在我看来, 复制构造默认是不安全的 – 实际上,在我看来,类不应该是默认可复制的,因为它们的实例variables之间的任何耦合都有可能导致默认的复制-constructor无效 。 迭代器从根本上不安全的存储? 或者,类应该默认是不可复制的? 下面我想到的解决scheme都是不可取的,因为它们不让我利用自动生成的拷贝构造函数: 手动实现我写的每个非平凡类的复制构造函数。 这不仅容易出错,而且要写一个复杂的课程也是很痛苦的。 […]
我知道如果你没有实现自己,编译器有时会提供一个默认的拷贝构造函数。 我很困惑这个构造函数是做什么的。 如果我有一个包含其他对象的类,其中没有一个具有声明的拷贝构造函数,那么行为是什么? 例如,像这样的一个类: class Foo { Bar bar; }; class Bar { int i; Baz baz; }; class Baz { int j; }; 现在,如果我这样做: Foo f1; Foo f2(f1); 默认的拷贝构造函数会做什么? Foo的编译器生成的拷贝构造函数是否会调用Bar的编译器生成的构造函数来复制一个bar ,然后调用Baz编译器生成的拷贝构造函数?