Redian新闻
>
老年工程师关于std::vector的几个问题
avatar
老年工程师关于std::vector的几个问题# Programming - 葵花宝典
X*n
1
昨天下班前溜去ALLEY接电话, 另一个同事先开溜把后门给带上了, 不得不得从前门
转回办公室, 刚好帮一双子美女HOLD门. 回去关了电脑收拾, 就见刚刚那美女又风风火
火的跑回盒子里拿东西. 我又从后门走去停车场.
刚进停车场, 那美女也已经到停车场了, 老远跟我兴奋的喊, “LOOK AT THAT!”
我转身一看,原来是道很长的彩虹.可惜, 从我站的位置, 眼角还看到身边的大垃圾箱,
所以有点遗憾的看了看就走了, 心想双子女真的很容易HIGH.
刚刚想起来, 她估计是跑回盒子里拿相机了.
不得不说, 我为什么那么容易拘谨而难得一HIGH呢. 如果我是狮子或白羊, 估计那
会就会也兴奋的跑过去看看她拍的好不好看, 问问她要不要拍一张站在彩虹里啥的了.
说到底, 那也却实是道很长的很好看的彩虹. 就因为不是在啥乡村野外开阔地看到,
就因为刚好旁边有个碍眼的垃圾箱? 我就让这些不必要的”可惜”而浪费了一个可以
”珍惜”的瞬间?

果真天性始然.
avatar
b*i
2
我们有个类,叫Pole吧
std::vector PoleAccess::Load(...){
std::vector poles;
... 动态生成Pole对象,加入到vector里面
return poles;
}
然后,有另一个类,HPleManager,里面要这样做
std::vector* PoleManager::LoadHole(
return new std::vector(PoleAccess::Load(...));
}
1 这样的话,是不是一开始有一个vector在栈上,然后为了返回堆上的指针,把内容复
制到了堆上?
2 这个new std::vector(Pole)是move constructor还是copy?
3 但是为了把栈上的变量移动到堆上,还是得copy吧?当然,只是一个vector容器的信
息而已,真正vector内容都在堆上吧。而且,内容指向的Pole对象也都在堆上。
4 这个过程RVO负责直接优化到堆上吗?我问这个问题是因为我需要把PoleAccess::
Load返回的每一个Pole对象做一个操作SetParent(this);这样的话,如果我断开
auto all = PoleAccess::Load(...);
for(auto pP:all) pP->SetParent(this);
return new std::vector(all);
这样还可能RVO吗?
avatar
s*i
3
因为你是摄影高手
avatar
z*h
4
我不是C++大牛,不过最近正好也碰到了同样的问题。
我觉得 new std::vector(PoleAccess::Load(...)) 是copy constructor复制
了一个object, 不是move.
你问什么不这样定义呢?
std::vector PoleManager::LoadHole(
std::vector poles = PoleAccess::Load(...);
return poles;
}
这样应该是用C++11的move semantics
你可以参照一下
https://stackoverflow.com/questions/15704565/efficient-way-to-return-a-
stdvector-in-c
我们公司的C++大牛们写的code都是return vector的,而不是pointer to vector.

【在 b***i 的大作中提到】
: 我们有个类,叫Pole吧
: std::vector PoleAccess::Load(...){
: std::vector poles;
: ... 动态生成Pole对象,加入到vector里面
: return poles;
: }
: 然后,有另一个类,HPleManager,里面要这样做
: std::vector* PoleManager::LoadHole(
: return new std::vector(PoleAccess::Load(...));
: }

avatar
P*I
5
你什么星座的?

,
.
到,

【在 X*****n 的大作中提到】
: 昨天下班前溜去ALLEY接电话, 另一个同事先开溜把后门给带上了, 不得不得从前门
: 转回办公室, 刚好帮一双子美女HOLD门. 回去关了电脑收拾, 就见刚刚那美女又风风火
: 火的跑回盒子里拿东西. 我又从后门走去停车场.
: 刚进停车场, 那美女也已经到停车场了, 老远跟我兴奋的喊, “LOOK AT THAT!”
: 我转身一看,原来是道很长的彩虹.可惜, 从我站的位置, 眼角还看到身边的大垃圾箱,
: 所以有点遗憾的看了看就走了, 心想双子女真的很容易HIGH.
: 刚刚想起来, 她估计是跑回盒子里拿相机了.
: 不得不说, 我为什么那么容易拘谨而难得一HIGH呢. 如果我是狮子或白羊, 估计那
: 会就会也兴奋的跑过去看看她拍的好不好看, 问问她要不要拍一张站在彩虹里啥的了.
: 说到底, 那也却实是道很长的很好看的彩虹. 就因为不是在啥乡村野外开阔地看到,

avatar
h*c
6
std::vector 只放class ojects吧,还是和java 混了,
不能放primitive type
avatar
t*c
7
这跟星座有关么,女生看到彩虹肯定比男生兴奋吧。
avatar
y*b
8
说的对,pointer to vector,那还要vector干嘛;
容器就是设计用来避免数组和指针这类不强健的用法,
还去new个容器。


: 我不是C 大牛,不过最近正好也碰到了同样的问题。

: 我觉得 new std::vector(PoleAccess::Load(...)) 是copy constructor
复制

: 了一个object, 不是move.

: 你问什么不这样定义呢?

: std::vector PoleManager::LoadHole(

: std::vector poles = PoleAccess::Load(...);

: return poles;

: }

: 这样应该是用C 11的move semantics

: 你可以参照一下



【在 z*******h 的大作中提到】
: 我不是C++大牛,不过最近正好也碰到了同样的问题。
: 我觉得 new std::vector(PoleAccess::Load(...)) 是copy constructor复制
: 了一个object, 不是move.
: 你问什么不这样定义呢?
: std::vector PoleManager::LoadHole(
: std::vector poles = PoleAccess::Load(...);
: return poles;
: }
: 这样应该是用C++11的move semantics
: 你可以参照一下

avatar
X*n
9
重点不在比较男女, 在反醒自己在生活中过于拘谨僵硬, 不够顺势而为, 不会随机应变

【在 t******c 的大作中提到】
: 这跟星座有关么,女生看到彩虹肯定比男生兴奋吧。
avatar
b*i
10
看来是copy,因为move需要std::move
那么,如果这个类的成员变量是vector poles的话,poleManager本身是另一个
类生成的singleton实例的指针,那么它的内容应该在堆上,这样的话整个过程从
PoleAcess::Load那里是在栈上生成一个vector,最后需要move到堆上吗?当然如果移
动,也不是很大数据量,因为只是这个vector自己的数据,而不是整个内容。
RVO能否知道本来为了要放到堆上而优化?

【在 z*******h 的大作中提到】
: 我不是C++大牛,不过最近正好也碰到了同样的问题。
: 我觉得 new std::vector(PoleAccess::Load(...)) 是copy constructor复制
: 了一个object, 不是move.
: 你问什么不这样定义呢?
: std::vector PoleManager::LoadHole(
: std::vector poles = PoleAccess::Load(...);
: return poles;
: }
: 这样应该是用C++11的move semantics
: 你可以参照一下

avatar
X*n
11
根本不是,
鄙视自己不满足, 只因为边角上的缺撼而不能投入去欣赏偶遇到的美好所在

【在 s*******i 的大作中提到】
: 因为你是摄影高手
avatar
z*h
12
https://www.cprogramming.com/c++11/rvalue-references-and-move-semantics-in-c
++11.html
vector变量是allocate在stack上,但是里面的东西是allocate在heap上,这样move
semantics就allocate一个新的vector object(里面就装size和一个pointer,不费内存
),但是C++11就不在heap上重新为vector里面的东西allocate memory了,它就偷偷地
把rvalue vector里面的pointer偷过来。
你的vector里面装的是指针,那么这些指针们allocate在heap上,每个再指向那些heap
上的pole们。我觉得你直接在vector里装pole不更省事吗?

【在 b***i 的大作中提到】
: 看来是copy,因为move需要std::move
: 那么,如果这个类的成员变量是vector poles的话,poleManager本身是另一个
: 类生成的singleton实例的指针,那么它的内容应该在堆上,这样的话整个过程从
: PoleAcess::Load那里是在栈上生成一个vector,最后需要move到堆上吗?当然如果移
: 动,也不是很大数据量,因为只是这个vector自己的数据,而不是整个内容。
: RVO能否知道本来为了要放到堆上而优化?

avatar
t*c
13
土象么

【在 X*****n 的大作中提到】
: 重点不在比较男女, 在反醒自己在生活中过于拘谨僵硬, 不够顺势而为, 不会随机应变
avatar
b*i
14
好像从函数内的栈上临时变量返回然后生成堆上的也是可以RVO的,所以声明vector的
指针完全没有必要。
但是vector内部存指针好像有必要。毕竟这个vector上存的类可能有继承关系,虚函数
什么的。

-c
heap

【在 z*******h 的大作中提到】
: https://www.cprogramming.com/c++11/rvalue-references-and-move-semantics-in-c
: ++11.html
: vector变量是allocate在stack上,但是里面的东西是allocate在heap上,这样move
: semantics就allocate一个新的vector object(里面就装size和一个pointer,不费内存
: ),但是C++11就不在heap上重新为vector里面的东西allocate memory了,它就偷偷地
: 把rvalue vector里面的pointer偷过来。
: 你的vector里面装的是指针,那么这些指针们allocate在heap上,每个再指向那些heap
: 上的pole们。我觉得你直接在vector里装pole不更省事吗?

avatar
P*I
15
土像会这么反省一件小事儿,然后写一篇文?
话说这和对摄影的热情也有一点关系,我当年看到彩虹后,赶忙跑回家拿了相机,开了
车,到最佳拍摄地,为了减少电线杆之类的东西,还爬到山顶上。
还有一次是看到一片野花,也是跑回去拿相机,又没电了,去买电池,当时还下了点雨
,半阴半晴的,跪在地上拍的照片,跪了一裤子泥。

【在 t******c 的大作中提到】
: 土象么
avatar
b*i
16
今天问了为什么,是为了标志load过了。开始的时候,是nullptr,如果load过了,可以
是empty的,可以是有内容的。这样就区分开了。

【在 y**b 的大作中提到】
: 说的对,pointer to vector,那还要vector干嘛;
: 容器就是设计用来避免数组和指针这类不强健的用法,
: 还去new个容器。
:
:
: 我不是C 大牛,不过最近正好也碰到了同样的问题。
:
: 我觉得 new std::vector(PoleAccess::Load(...)) 是copy constructor
: 复制
:
: 了一个object, 不是move.
:
: 你问什么不这样定义呢?
:
: std::vector PoleManager::LoadHole(

avatar
X*n
17
呵呵, 这难道是你们水象的专利?
至少你是有想去拍,和真的拍了. 我只是瞟了一眼就走了. 当然, 我根本不是什么摄影爱好者.

【在 P**I 的大作中提到】
: 土像会这么反省一件小事儿,然后写一篇文?
: 话说这和对摄影的热情也有一点关系,我当年看到彩虹后,赶忙跑回家拿了相机,开了
: 车,到最佳拍摄地,为了减少电线杆之类的东西,还爬到山顶上。
: 还有一次是看到一片野花,也是跑回去拿相机,又没电了,去买电池,当时还下了点雨
: ,半阴半晴的,跪在地上拍的照片,跪了一裤子泥。

avatar
l*r
18
问题有点凌乱,粗略看了一眼,没见过用得这么绕的。如果你还要考虑多态,vector里
必须装指针的话,根据情况放unique_ptr或者shared_ptr不就好了?unique_ptr的话要
自己一个个move,不能直接靠copy vector来做。
avatar
X*n
19
话说突然想起来和老妈去机场接老爸的时候, 我留意到他们的第一个动作居然是握手.
差点没笑趴了,
所以, 还是得继续敲打这个貌似天蝎的老爸, "有时你或许可以这么想, 疼老婆也是疼
给儿子看的,这次省着不疼,留着不哄,难道下次还能用哦?"
avatar
L*8
20
std::vector啥都能放 不过不要放bool

【在 h**********c 的大作中提到】
: std::vector 只放class ojects吧,还是和java 混了,
: 不能放primitive type

avatar
H*y
21
lol

【在 X*****n 的大作中提到】
: 话说突然想起来和老妈去机场接老爸的时候, 我留意到他们的第一个动作居然是握手.
: 差点没笑趴了,
: 所以, 还是得继续敲打这个貌似天蝎的老爸, "有时你或许可以这么想, 疼老婆也是疼
: 给儿子看的,这次省着不疼,留着不哄,难道下次还能用哦?"

avatar
b*i
22
我们是要放unique_ptr的,但是即使这样,有的时候有些函数需要返回裸指针的数组,
就要vector这样的。

【在 l*******r 的大作中提到】
: 问题有点凌乱,粗略看了一眼,没见过用得这么绕的。如果你还要考虑多态,vector里
: 必须装指针的话,根据情况放unique_ptr或者shared_ptr不就好了?unique_ptr的话要
: 自己一个个move,不能直接靠copy vector来做。

avatar
H*y
23
有时候是可以压制的?
我年轻的时候就觉得什么都不好玩,兴奋不起来,现在反而好多了
随行而为就好

根本不是,
鄙视自己不满足, 只因为边角上的缺撼而不能投入去欣赏偶遇到的美好所在

【在 X*****n 的大作中提到】
: 根本不是,
: 鄙视自己不满足, 只因为边角上的缺撼而不能投入去欣赏偶遇到的美好所在

avatar
L*8
24
为啥不能vector 是不是没有copy/move constructor
古老的c++程序猿一般都没有这个概念

【在 b***i 的大作中提到】
: 我们是要放unique_ptr的,但是即使这样,有的时候有些函数需要返回裸指针的数组,
: 就要vector这样的。

avatar
H*y
25
我也就一边开车一边照了个双彩虹
还担心被抓

土像会这么反省一件小事儿,然后写一篇文?
话说这和对摄影的热情也有一点关系,我当年看到彩虹后,赶忙跑回家拿了相机,开了
车,到最佳拍摄地,为了减少电线杆之类的东西,还爬到山顶上。
还有一次是看到一片野花,也是跑回去拿相机,又没电了,去买电池,当时还下了点雨
,半阴半晴的,跪在地上拍的照片,跪了一裤子泥。

【在 P**I 的大作中提到】
: 土像会这么反省一件小事儿,然后写一篇文?
: 话说这和对摄影的热情也有一点关系,我当年看到彩虹后,赶忙跑回家拿了相机,开了
: 车,到最佳拍摄地,为了减少电线杆之类的东西,还爬到山顶上。
: 还有一次是看到一片野花,也是跑回去拿相机,又没电了,去买电池,当时还下了点雨
: ,半阴半晴的,跪在地上拍的照片,跪了一裤子泥。

avatar
i*c
26
new std::vector(PoleAccess::Load(...)) 是 move construct,PoleAccess:
:Load的返回值没有名字,是rvalue

【在 z*******h 的大作中提到】
: 我不是C++大牛,不过最近正好也碰到了同样的问题。
: 我觉得 new std::vector(PoleAccess::Load(...)) 是copy constructor复制
: 了一个object, 不是move.
: 你问什么不这样定义呢?
: std::vector PoleManager::LoadHole(
: std::vector poles = PoleAccess::Load(...);
: return poles;
: }
: 这样应该是用C++11的move semantics
: 你可以参照一下

avatar
c*1
27
RE
avatar
i*s
28
你把std::vector 想象成 int, 然后就会清楚为什么这个是没有问题的了。
详细的可看这里:https://stackoverflow.com/questions/22655059/why-it-is-ok-to
-return-vector-from-function

【在 b***i 的大作中提到】
: 我们有个类,叫Pole吧
: std::vector PoleAccess::Load(...){
: std::vector poles;
: ... 动态生成Pole对象,加入到vector里面
: return poles;
: }
: 然后,有另一个类,HPleManager,里面要这样做
: std::vector* PoleManager::LoadHole(
: return new std::vector(PoleAccess::Load(...));
: }

avatar
X*n
29
...不担心出事, 反而担心被抓? 汗
只要不是被车流夹住了, 干脆就到路边停下咯.

【在 H**********y 的大作中提到】
: 我也就一边开车一边照了个双彩虹
: 还担心被抓
:
: 土像会这么反省一件小事儿,然后写一篇文?
: 话说这和对摄影的热情也有一点关系,我当年看到彩虹后,赶忙跑回家拿了相机,开了
: 车,到最佳拍摄地,为了减少电线杆之类的东西,还爬到山顶上。
: 还有一次是看到一片野花,也是跑回去拿相机,又没电了,去买电池,当时还下了点雨
: ,半阴半晴的,跪在地上拍的照片,跪了一裤子泥。

avatar
h*l
30
1 这样的话,是不是一开始有一个vector在栈上,然后为了返回堆上的指针,把内容复
制到了堆上?
yeah, just copy the container info from stack to heap.
2 这个new std::vector(Pole)是move constructor还是copy?
should be move as the method returns r-value.
3 但是为了把栈上的变量移动到堆上,还是得copy吧?当然,只是一个vector容器的信
息而已,真正vector内容都在堆上吧。而且,内容指向的Pole对象也都在堆上。
move constructor of the vector container is used, the container information
is copied from stack to heap, the vector elements (Pole*) are moved
4 这个过程RVO负责直接优化到堆上吗?我问这个问题是因为我需要把PoleAccess::
Load返回的每一个Pole对象做一个操作SetParent(this);这样的话,如果我断开
I doubt that RVO can do that. The container probably needs to be created on
the stack first.
BTW, you can set breakpoint in vector header or check assembly code to see
what happens.

【在 b***i 的大作中提到】
: 我们有个类,叫Pole吧
: std::vector PoleAccess::Load(...){
: std::vector poles;
: ... 动态生成Pole对象,加入到vector里面
: return poles;
: }
: 然后,有另一个类,HPleManager,里面要这样做
: std::vector* PoleManager::LoadHole(
: return new std::vector(PoleAccess::Load(...));
: }

avatar
x*i
31
照片?
avatar
l*r
32

那你也只能这么做了,麻烦的就是ownership自己维护。
另外其实new一个vector看着也别扭,如果你用c++17的话,可以考虑把返回值改成std:

【在 b***i 的大作中提到】
: 我们是要放unique_ptr的,但是即使这样,有的时候有些函数需要返回裸指针的数组,
: 就要vector这样的。

avatar
y*b
33
new容器是不是用智能指针指向容器更好啊?后者倒是常见。

【在 b***i 的大作中提到】
: 今天问了为什么,是为了标志load过了。开始的时候,是nullptr,如果load过了,可以
: 是empty的,可以是有内容的。这样就区分开了。

相关阅读
logo
联系我们隐私协议©2024 redian.news
Redian新闻
Redian.news刊载任何文章,不代表同意其说法或描述,仅为提供更多信息,也不构成任何建议。文章信息的合法性及真实性由其作者负责,与Redian.news及其运营公司无关。欢迎投稿,如发现稿件侵权,或作者不愿在本网发表文章,请版权拥有者通知本网处理。