std :: vector가 push_back으로 객체를 복사합니까?
valgrind로 많은 조사를 한 후에 std :: vector가 push_back하려는 객체의 사본을 만든다는 결론을 내 렸습니다.
정말 맞습니까? 벡터는 복사본없이 객체의 참조 나 포인터를 유지할 수 없습니다!
감사
예, std::vector<T>::push_back()
인수의 복사본을 만들어 벡터에 저장합니다. 벡터의 객체에 대한 포인터를 저장하려면 std::vector<whatever*>
대신을 만드십시오 std::vector<whatever>
.
그러나 벡터가 참조를 보유하고있는 동안 포인터가 참조하는 객체는 유효하게 유지해야합니다 (RAII 관용구를 사용하는 스마트 포인터는 문제를 해결합니다).
예, std::vector
사본을 저장합니다. vector
물체의 예상 수명이 무엇인지 어떻게 알 수 있습니까?
객체의 소유권을 전송하거나 공유하려면 포인터를 사용하십시오 shared_ptr
. 부스트 또는 TR1 과 같은 스마트 포인터는 리소스 관리를 용이하게합니다.
C ++ 11부터 모든 표준 컨테이너 ( std::vector
, std::map
등)는 이동 의미론을 지원하므로 이제 rvalue를 표준 컨테이너에 전달하고 사본을 피할 수 있습니다.
// Example object class.
class object
{
private:
int m_val1;
std::string m_val2;
public:
// Constructor for object class.
object(int val1, std::string &&val2) :
m_val1(val1),
m_val2(std::move(val2))
{
}
};
std::vector<object> myList;
// #1 Copy into the vector.
object foo1(1, "foo");
myList.push_back(foo1);
// #2 Move into the vector (no copy).
object foo2(1024, "bar");
myList.push_back(std::move(foo2));
// #3 Move temporary into vector (no copy).
myList.push_back(object(453, "baz"));
// #4 Create instance of object directly inside the vector (no copy, no move).
myList.emplace_back(453, "qux");
또는 다양한 스마트 포인터를 사용하여 대부분 동일한 효과를 얻을 수 있습니다.
std::unique_ptr
예
std::vector<std::unique_ptr<object>> myPtrList;
// #5a unique_ptr can only ever be moved.
auto pFoo = std::make_unique<object>(1, "foo");
myPtrList.push_back(std::move(pFoo));
// #5b unique_ptr can only ever be moved.
myPtrList.push_back(std::make_unique<object>(1, "foo"));
std::shared_ptr
예
std::vector<std::shared_ptr<object>> objectPtrList2;
// #6 shared_ptr can be used to retain a copy of the pointer and update both the vector
// value and the local copy simultaneously.
auto pFooShared = std::make_shared<object>(1, "foo");
objectPtrList2.push_back(pFooShared);
// Pointer to object stored in the vector, but pFooShared is still valid.
std :: vector는 항상 벡터에 저장되는 모든 내용을 복사합니다.
If you are keeping a vector of pointers, then it will make a copy of the pointer, but not the instance being to which the pointer is pointing. If you are dealing with large objects, you can (and probably should) always use a vector of pointers. Often, using a vector of smart pointers of an appropriate type is good for safety purposes, since handling object lifetime and memory management can be tricky otherwise.
Not only does std::vector make a copy of whatever you're pushing back, but the definition of the collection states that it will do so, and that you may not use objects without the correct copy semantics within a vector. So, for example, you do not use auto_ptr in a vector.
Relevant in C++11 is the emplace
family of member functions, which allow you to transfer ownership of objects by moving them into containers.
The idiom of usage would look like
std::vector<Object> objs;
Object l_value_obj { /* initialize */ };
// use object here...
objs.emplace_back(std::move(l_value_obj));
The move for the lvalue object is important as otherwise it would be forwarded as a reference or const reference and the move constructor would not be called.
if you want not the copies; then the best way is to use a pointer vector(or another structure that serves for the same goal). if you want the copies; use directly push_back(). you dont have any other choice.
Why did it take a lot of valgrind investigation to find this out! Just prove it to yourself with some simple code e.g.
std::vector<std::string> vec;
{
std::string obj("hello world");
vec.push_pack(obj);
}
std::cout << vec[0] << std::endl;
If "hello world" is printed, the object must have been copied
참고URL : https://stackoverflow.com/questions/2275076/is-stdvector-copying-the-objects-with-a-push-back
'IT' 카테고리의 다른 글
Apache Commons equals / hashCode 빌더 (0) | 2020.06.07 |
---|---|
ES6 모듈을 조건부로 가져 오려면 어떻게해야합니까? (0) | 2020.06.07 |
wait () 호출시 IllegalMonitorStateException (0) | 2020.06.07 |
펑크 (0) | 2020.06.07 |
정규식 패턴을 적용하기 전에 이스케이프 할 수있는 PHP 함수가 있습니까? (0) | 2020.06.07 |