Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is there an equivalent of c++ shared_ptr in swift 3?

Tags:

c++

swift

I know strong (default) and weak (with the weak keyword) references in swift 3, but is there an equivalent of shared references?

Thanks

like image 937
Bob5421 Avatar asked Oct 26 '25 02:10

Bob5421


2 Answers

The memory management paradigm in Swift is different from C++ since it inherits the retain-release mechanism (through ARC) from Objective-C. As you might expect, C++'s solution puts less responsibility on the compiler, is more expressive and optimised but also more complex to work with.

So, to answer your question: strong (which is default) works basically like shared_ptr, weak is like weak_ptr and unique_ptr doesn't have a direct equivalent. However, some strong vars might act like unique_ptr if the compiler is able to guarantee the uniqueness of the pointer (e.g. you create and destroy an object in the same scope - like a function's body - without assigning it to any var)

Of course, this only applies to reference types. Value types are just copied.

like image 56
Rad'Val Avatar answered Oct 28 '25 15:10

Rad'Val


Swift applies ARC (automatic reference counting) of strong references to decide when to free up memory used by a reference type instance (namely, when the number of strong references to that object is zero). ARC and its reference counting runs automatically, but holds similiarities to the explicit use of C++'s std::shared_ptr; the latter will allow an object pointed to (by shared ptrs) to be destroyed (e.g. by a supplied deletor) only when all smart pointers pointing to the object has gone out of scope or been explicitly reset (/nulled).

In the example above, you can consider the strong immutables (references) foo and bar (the latter return from foobar()) as the std::smart_ptr's equivalents of C++: they both point to the same Foo object, and only when both are out of scope will the object be deinitialized.

class Foo {
    init() { print("initializing") }
    deinit { print("deinitialized") }
}

func foobar() -> Foo {
    let foo = Foo() // strong reference
    let bar = foo   // another strong reference 
    // total "shared" count is now 2
    return bar
    // reference associateced with 'foo' goes 
    // out of scope, but the reference associateced
    // with 'bar' is returned from the function, and
    // thus, ARC still keeps the Foo instance alive.
}

func bar() {
    print("calling foobar ...")
    let bar = foobar() // retains the reference from 'bar' in foobar()
    print("foo() is now out of scope")
    print("leaving bar() scope ...")
} // 'bar' of bar() goes out of scope: Foo object should be deinitialized

bar()
/* calling foobar ...
   initializing
   foo() is now out of scope
   leaving bar() scope ...
   deinitialized             */
/* ^^^^^^^^^^^^^- ok */
like image 40
dfrib Avatar answered Oct 28 '25 16:10

dfrib