for (int i = 0; i < 10; i++)
{
nueron temp; // my Class
_inputNuerons.push_back(temp); // _inputNuerons is a std::vector
}
据我所知,C ++在到达for循环的}括号时释放临时对象。 但是将对象存储在std :: vector中会使该对象稍后在程序中使用吗? 现在,当我尝试访问for循环外的“temp”nueron时,程序崩溃了。
如何将我的对象存储在std :: vector中,以便以后可以使用?
答案 0 :(得分:1)
您的神经元对象将在阻止结束时被销毁。 您应该使用动态分配,并将指针存储在向量中的该对象上。
for (int i = 0; i < 10; i++)
{
nueron* temp = new neuron(); // my Class
_inputNuerons.push_back(temp); // _inputNuerons is a std::vector
}
_inputNeurons集合应该是神经元指针的集合。
答案 1 :(得分:1)
如何将我的对象存储在std :: vector中以使其可用 以后呢?
如果您不提供自己的(并且不删除它),编译器会为您创建一个复制构造函数。
compiler-created-copy-constructor的主体不为空,它将传递的nueron对象(temp)的所有数据成员复制到在向量元素中创建的对象。
因此以下工作正常:
for (int i = 0; i < 10; i++)
{
Nueron temp; // my Class
_inputNuerons.push_back(temp); // _inputNuerons is a std::vector
}
新的Nueron temp在左支撑处构建,开始循环并且
对象temp在结束循环的右括号中被销毁,
push_back将temp(通过编译器提供的copy ctor)复制到向量的下一个元素
这里有一些代码来说明编译器生成的默认复制ctor。
请注意,此默认ctor为每个Nueron提供唯一值。这只是为了好玩,并且很容易看到所有元素都是使用编译器提供的默认代码进行复制和初始化的。
注1 - 您可以在同一行中调整和填充矢量,
和
注2 - 您可以在堆栈上构建一个元素,并应用push_back()。
示例代码:
int seqNum(bool restart=false) // when true restart seqnum
{
static int SeqNum = 0;
if(restart) SeqNum = 0;
return (SeqNum++);
}
class Nueron
{
public:
Nueron() : i1(seqNum()) {} // you provide the default ctor
// default dtor - use the compiler provided dtor
// default copy ctor - use the compiler provided copy ctor
std::string show()
{
std::stringstream ss;
ss << DTB::digiComma(i1);
return (ss.str());
};
private:
int i1;
};
void headerShow(std::stringstream& ss)
{
ss << " vector element size: " << std::setw(5) << sizeof(Nueron) << " bytes\n" // header
<< "\n"
<< std::setw(15) << "element"
<< std::setw(15) << "vector"
<< std::setw(20) << "bytes stack use"
<< std::setw(24) << "bytes heap use\n"
<< std::setw(15) << " count"
<< std::setw(15) << "capacity"
<< std::setw(20) << "'sizeof(vector)'"
<< std::setw(24) << " (element count * element size)\n";
}
void infoShow(std::vector<Nueron>& n, std::stringstream& ss)
{
ss << std::setw(15) << DTB::digiComma(n.size()) // element count
<< std::setw(15) << DTB::digiComma(n.capacity()) // vector capacity
<< std::setw(18) << DTB::digiComma(sizeof(n)) // bytes stack use
<< std::setw(24) << DTB::digiComma (n.size() * sizeof(Nueron)) // bytes heap use
<< std::endl;
}
void contentShow(size_t indx,
std::vector<Nueron>& n,
std::stringstream& ss,
size_t limit1,
size_t limit2 = 0)
{
ss << " content " << indx << ": ";
for (size_t i=0; i<limit1; ++i)
ss << n[i].show() << " ";
if(limit2)
{
ss << "... ";
for (size_t i=(n.size()-limit2); i<n.size(); ++i)
ss << std::setw(10) << n[i].show() << " ";
}
ss << std::endl;
}
int t207a(void)
{
std::cout << "\n============================================= " << "\nt207a():" << std::endl;
(void)seqNum(true); // restart seq from 0
std::stringstream ss1;
std::stringstream ss2;
std::vector<Nueron> neuron(5); // default ctor used 5 times
headerShow(ss1);
infoShow(neuron, ss1);
// add 5 more using 'free' copy ctor
for (size_t i=0; i<5; ++i)
{
Nueron temp; // use ctor
neuron.push_back(temp); // use compiler provided copy ctor
}
infoShow(neuron, ss1);
ss2 << "\n";
contentShow(1, neuron, ss2, 10, 0);
std::cout << ss2.str() << std::endl << ss1.str() << std::endl;
// neuron dtor runs here
return(0);
}
报告:
============================================= t207a( ):
内容1:1 2 3 4 5 6 7 8 9 10
向量元素大小:4个字节
element vector bytes stack use bytes heap use count capacity 'sizeof(vector)' (element count * element size) 5 5 24 20 10 10 24 40
编辑 -
关于可能被解释为建议将向量本身放入堆中的其他答案......我准备了以下代码来说明为什么这不是必需的。
int t207b(void)
{
std::cout << "\n============================================= " << "\nt207b():" << std::endl;
(void)seqNum(true); // restart seq from 0
std::stringstream ss1;
std::stringstream ss2;
std::vector<Nueron> neuron; // no elements
headerShow(ss1);
infoShow(neuron, ss1);
size_t cap1 = neuron.capacity();
// add elements using 'free' copy ctor
do
{
{
Nueron temp; // use ctor
neuron.push_back(temp); // use compiler provided copy ctor
}
size_t cap2 = neuron.capacity();
if(cap2 != cap1)
{
cap1 = cap2;
infoShow(neuron, ss1);
if (cap2 > 500000000) break;
// 12345678
}
}while(1);
contentShow(1, neuron, ss2, 10, 0);
std::cout << ss1.str() << "\n" << std::endl << ss2.str() << std::endl;
// neuron dtor runs here
return(0);
}
输出:
============================================= <无线电通信/> t207b():向量元素大小:4个字节
element vector bytes stack use bytes heap use count capacity 'sizeof(vector)' (element count * element size) 0 0 24 0 1 1 24 4 2 2 24 8 3 4 24 12 5 8 24 20 9 16 24 36 17 32 24 68 33 64 24 132 65 128 24 260 129 256 24 516 257 512 24 1,028 513 1,024 24 2,052 1,025 2,048 24 4,100 2,049 4,096 24 8,196 4,097 8,192 24 16,388 8,193 16,384 24 32,772 16,385 32,768 24 65,540 32,769 65,536 24 131,076 65,537 131,072 24 262,148 131,073 262,144 24 524,292 262,145 524,288 24 1,048,580 524,289 1,048,576 24 2,097,156 1,048,577 2,097,152 24 4,194,308 2,097,153 4,194,304 24 8,388,612 4,194,305 8,388,608 24 16,777,220 8,388,609 16,777,216 24 33,554,436 16,777,217 33,554,432 24 67,108,868 33,554,433 67,108,864 24 134,217,732 67,108,865 134,217,728 24 268,435,460 134,217,729 268,435,456 24 536,870,916 268,435,457 536,870,912 24 1,073,741,828
摘要 - 对于g ++版本4.9.2,在Ubuntu 15.04上:
第3列显示,无论向量中的元素数量或元素的大小如何,堆栈影响始终只有24个字节。 (即sizeof())
第1列和第2列显示了向量增长的实现选择(即二进制)
第4列显示了向量中的总字节数。 Vector保证所有元素都背靠背。在这个例子中,代码退出时输入了500万个元素,并且(我假设)动态内存为1 GBy。
此堆栈影响非常小,您可能不希望将向量推送到堆中。