1
3
如果FOO或BAR可能在复制时抛出,则应考虑使用复制和交换分配。如果看不到这些类的定义,就不可能说出它们是否可以。如果没有看到他们发布的界面,就不可能说他们将来是否会这样做,而你没有意识到。 正如jalf所说,使用auto-ptr有点危险。它在复制或分配时不符合您的要求。快速看一下,我认为您的代码从未允许复制或分配IMPL成员,所以这可能是正常的。
但是,如果您可以使用作用域指针,那么编译器将为您做一些棘手的工作,检查它是否没有被错误地修改过。
|
2
2
PIMPL有几个问题。 首先,尽管不明显:如果使用PIMPL,则必须定义复制构造函数/赋值运算符和析构函数(现在称为“可怕的3”)。 您可以通过使用适当的语义创建一个好的模板类来缓解这一问题。 问题是,如果编译器开始为您定义“可怕的3”中的一个,因为您已经使用了forward声明,它知道如何调用所声明的对象forward的“可怕的3”…
最令人惊讶的是:它似乎与
作为奖励,我自己的PIMPL类:
考虑不多(尤其是演员阵容问题),但有一些细节:
你还得写“可怕的3”。但至少你可以用价值语义来处理它。 编辑 :在Frerich Raabe的鼓励下,这是一个懒惰的版本,当写三大(现在是四大)是一个麻烦。 其思想是“捕获”完整类型可用的信息,并使用抽象接口使其可操作。
用这个,一个 真 编译防火墙:
|
3
0
我一直在同一个问题上挣扎。我认为答案是: 只要定义了复制和分配操作符来执行明智的操作,就可以执行您建议的操作。 重要的是要理解STL容器创建了事物的副本。所以:
其输出为:
也就是说,向量存储了一个C的副本,而不是C本身。 因此,当您将它重写为PIMPL类时,您会得到:
注意,为了简洁起见,我对pimpl习惯用法做了一些修改。如果您尝试将其推送到一个向量中,它仍会尝试创建
安
什么
(或类似的内容-无法记住所有模板参数)。如果
所以您需要决定类的底层语义是什么。如果仍然需要“复制所有内容”行为,则需要提供一个正确实现该行为的复制构造函数:
现在,当您尝试获取一个sampleimpl的副本时,您还将获得其impl结构的副本,该结构由copy sampleimpl拥有。如果您将一个拥有大量私有数据成员并且在STL容器中使用的对象转换为PIMPL类,那么这可能是您想要的,因为它提供了与原始对象相同的语义。但是请注意,将对象推送到一个向量中会慢得多,因为现在复制对象时涉及到动态内存分配。 如果你决定 不要 如果需要这种复制行为,那么另一种方法是让sampleimpl的副本共享底层的impl对象。在这种情况下,不再清楚(甚至是定义良好的)sampleimpl对象拥有底层impl。如果所有权不明确地属于一个地方,那么std::auto-ptr是存储它的错误选择。 你需要使用其他东西,可能是一个增强模板。
编辑
:我认为上面的复制构造函数和赋值运算符是异常安全的。
只要
|
rookie · 检查函数模板的所有参数包参数是否属于int 1 年前 |
ivaigult · -W转换和隐式字符串到布尔类型转换 1 年前 |
rainer · 后台插入程序的初始化 1 年前 |
Community wiki · 以理智、安全和高效的方式复制文件 1 年前 |
Shefali Kanaujia · 对C中向量的向量进行排序++ 1 年前 |
Ma Joonyoung · 粗粒度和细粒度链表的时间比较 1 年前 |