Vyk*_*tor 9 c++ containers vector copy-constructor
我正在使用这两个课程
// This is generic data structure containing some binary data
class A {
public:
A();
A(const A&);
~A();
}
// Main data container
class B {
public:
B();
B( const B&);
~B();
protected:
std::vector<A *> data;
}
// Copy constructor for class b
B::B( const B& orig):data() {
for( std::vector<A *>::const_iterator it = orig.data.begin();
it < orig.data.end(); ++it){
data.push_back( new A( *(*it)));
}
}
Run Code Online (Sandbox Code Playgroud)
我想这堂课会做到这一点,但我找到了如何达到完美的目标.
首先:data() - 这是初始化空向量所需的初始化(这是编写一个好的和干净的代码的一部分)?
如何vector::iterator在复制构造函数中使用,我找到的唯一方法就是我写入代码的方法(对于复制构造函数,const应该是必需的).
仅复制矢量会复制指针值而不是整个对象?
最后新的数据初始化...有什么办法可以用较小的代码替换整个循环和/或是否有任何标准如何为包含对象指针的std :: containers编写复制构造函数?
子问题:我假设使用vector<A *>比各种原因更适合和有效vector<A>(不是每次复制,决定是否(不)复制对象的权力......)
Set*_*gie 10
这data()不是必需的,因为在输入构造函数之前将自动完成向量.您只需初始化POD类型的成员或没有默认构造函数(或引用,常量等)的类型.
您可以使用另一个元素的元素数初始化向量,以便向量在增长时不必调整自身大小.如果你不这样做,你将从一个小向量开始,并通过分配和重新分配逐步达到目标大小.这将使矢量从一开始就具有正确的大小:
B::B(const B& orig) : data(orig.data.size()) {
for (std::size_t i = 0; i < orig.data.size(); ++i)
data[i] = new A(*orig.data[i]);
}
Run Code Online (Sandbox Code Playgroud)
请注意,您不再使用,push_back因为向量已经填充了orig.data.size()多个默认构造的元素(NULL在指针的情况下).
这也会减少代码,因为您可以使用整数来迭代它而不是迭代器.
如果你真的想使用迭代器,你可以这样做
B::B(const B& orig) : data(orig.data.size()) {
// auto is preferable here but I don't know if your compiler supports it
vector<A*>::iterator thisit = data.begin();
vector<A*>::const_iterator thatit = orig.data.cbegin();
for (; thatit != orig.data.cend(); ++thisit, ++thatit)
*thisit = new A(**thatit);
}
Run Code Online (Sandbox Code Playgroud)
这样做的好处是它可以list通过改变迭代器的类型来处理其他容器类型(例如)(当然,如果你有的话,它会消失auto).
如果要添加异常安全性,则需要一个try/catch块:
B::B(const B& orig) : data(orig.data.size()) {
try {
// auto is preferable here but I don't know if your compiler supports it
vector<A*>::iterator thisit = data.begin();
vector<A*>::const_iterator thatit = orig.data.cbegin();
for (; thatit != orig.data.cend(); ++thisit, ++thatit)
*thisit = new A(**thatit);
} catch (...) {
for (vector<A*>::iterator i = data.begin(); i != data.end(); ++i)
if (!*i)
break;
else
delete *i;
throw;
}
}
Run Code Online (Sandbox Code Playgroud)
这样,如果其中一个new调用抛出异常,您就不会有内存泄漏.当然,try/catch如果你宁愿这样做,你可以使用没有迭代器的方式.
| 归档时间: |
|
| 查看次数: |
12188 次 |
| 最近记录: |