Programing

std :: unique_ptr을 함수에 어떻게 전달할 수 있습니까?

crosscheck 2020. 12. 4. 07:53
반응형

std :: unique_ptr을 함수에 어떻게 전달할 수 있습니까?


std::unique_ptr함수에를 어떻게 전달할 수 있습니까? 다음과 같은 수업이 있다고 가정 해 보겠습니다.

class A
{
public:
    A(int val)
    {
        _val = val;
    }

    int GetVal() { return _val; }
private:
    int _val;
};

다음은 컴파일되지 않습니다.

void MyFunc(unique_ptr<A> arg)
{
    cout << arg->GetVal() << endl;
}

int main(int argc, char* argv[])
{
    unique_ptr<A> ptr = unique_ptr<A>(new A(1234));
    MyFunc(ptr);

    return 0;
}

std::unique_ptr함수에를 전달할 수없는 이유는 무엇 입니까? 확실히 이것이 구조의 주요 목적입니까? 또는 C ++위원회는 원시 C 스타일 포인터로 돌아가서 다음과 같이 전달하도록 의도 했습니까?

MyFunc(&(*ptr)); 

그리고 무엇보다도 이상하게도 이것이 통과하는 데 적합한 방법 인 이유는 무엇입니까? 끔찍하게 일관성이 없어 보입니다.

MyFunc(unique_ptr<A>(new A(1234)));

여기에는 기본적으로 두 가지 옵션이 있습니다.

참조로 스마트 포인터 전달

void MyFunc(unique_ptr<A> & arg)
{
    cout << arg->GetVal() << endl;
}

int main(int argc, char* argv[])
{
    unique_ptr<A> ptr = unique_ptr<A>(new A(1234));
    MyFunc(ptr);
}

스마트 포인터를 함수 인수로 이동

이 경우 어설 션이 유지됩니다!

void MyFunc(unique_ptr<A> arg)
{
    cout << arg->GetVal() << endl;
}

int main(int argc, char* argv[])
{
    unique_ptr<A> ptr = unique_ptr<A>(new A(1234));
    MyFunc(move(ptr));
    assert(ptr == nullptr)
}

당신은 그것을 가치로 전달하고 있습니다. 이것은 복사본을 만드는 것을 의미합니다. 그다지 독특하지 않을까요?

값을 이동할 수 있지만 이는 객체의 소유권과 수명 제어를 함수에 전달하는 것을 의미합니다.

개체의 수명이 MyFunc에 대한 호출 수명 동안 존재하도록 보장되는 경우를 통해 원시 포인터를 전달하면됩니다 ptr.get().


unique_ptr함수에를 전달할 수없는 이유는 무엇 입니까?

unique_ptr이동 생성자는 있지만 복사 생성자는 없기 때문에 그렇게 할 수 없습니다 . 표준에 따르면 이동 생성자는 정의되어 있지만 복사 생성자는 정의되지 않은 경우 복사 생성자는 삭제됩니다.

12.8 클래스 객체 복사 및 이동

...

7 클래스 정의가 복사 생성자를 명시 적으로 선언하지 않으면 암시 적으로 선언됩니다. 클래스 정의가 이동 생성자 또는 이동 할당 연산자를 선언하는 경우 암시 적으로 선언 된 복사 생성자는 삭제 된 것으로 정의됩니다.

You can pass the unique_ptr to the function by using:

void MyFunc(std::unique_ptr<A>& arg)
{
    cout << arg->GetVal() << endl;
}

and use it like you have:

or

void MyFunc(std::unique_ptr<A> arg)
{
    cout << arg->GetVal() << endl;
}

and use it like:

std::unique_ptr<A> ptr = std::unique_ptr<A>(new A(1234));
MyFunc(std::move(ptr));

Important Note

Please note that if you use the second method, ptr does not have ownership of the pointer after the call to std::move(ptr) returns.

void MyFunc(std::unique_ptr<A>&& arg) would have the same effect as void MyFunc(std::unique_ptr<A>& arg) since both are references.

In the first case, ptr still has ownership of the pointer after the call to MyFunc.


Why can I not pass a unique_ptr into a function?

You can, but not by copy - because std::unique_ptr<> is not copy-constructible.

Surely this is the primary purpose of the construct?

Among other things, std::unique_ptr<> is designed to unequivocally mark unique ownership (as opposed to std::shared_ptr<> ).

And most strangely of all, why is this an OK way of passing it?

Because in that case, there is no copy-construction.


As MyFunc doesn't take ownership, it would be better to have:

void MyFunc(const A* arg)
{
    assert(arg != nullptr); // or throw ?
    cout << arg->GetVal() << endl;
}

or better

void MyFunc(const A& arg)
{
    cout << arg.GetVal() << endl;
}

If you really want to take ownership, you have to move your resource:

std::unique_ptr<A> ptr = std::make_unique<A>(1234);
MyFunc(std::move(ptr));

or pass directly a r-value reference:

MyFunc(std::make_unique<A>(1234));

std::unique_ptr doesn't have copy on purpose to guaranty to have only one owner.


Since unique_ptr is for unique ownership, if you want to pass it as argument try

MyFunc(move(ptr));

But after that the state of ptr in main will be nullptr.

참고URL : https://stackoverflow.com/questions/30905487/how-can-i-pass-stdunique-ptr-into-a-function

반응형