Skip to content
Closed
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
36 changes: 33 additions & 3 deletions documentation/cxx-interop/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -1239,7 +1239,7 @@ To specify that a C++ type is a shared reference type, use the `SWIFT_SHARED_REF
class SharedObject : IntrusiveReferenceCounted<SharedObject> {
public:
SharedObject(const SharedObject &) = delete; // non-copyable

SharedObject();
static SharedObject* create();
void doSomething();
} SWIFT_SHARED_REFERENCE(retainSharedObject, releaseSharedObject);
Expand All @@ -1250,11 +1250,41 @@ void releaseSharedObject(SharedObject *);

Now that `SharedObject` is imported as a reference type in Swift, the programmer will be able to use it in the following manner:
```swift
let object = SharedObject.create()
object.doSomething()
// The C++ constructor is imported as a Swift initializer
let object1 = SharedObject.create()
let object2 = SharedObject()
object1.doSomething()
object2.doSomething()
// `object` will be released here.
```

You can create instances of `SharedObject` directly from Swift by calling its C++ constructor through a Swift initializer.

**NOTE:** Swift uses *default* `new` operator for constructing c++ shared reference types. If you'd like to prevent Swift from importing constructors as initializers, you can also delete the *default* `new` operator in C++.


Alternatively, you can also construct instances of `SharedObject` using a user-defined static factory function, provided that the factory function is annotated with `SWIFT_NAME("init(...)")`, where the number of `_` placeholders matches the number of parameters in the factory function.

For example, consider a factory that performs custom allocation or returns a singleton instance:

```cpp
struct SharedObject {
static SharedObject* make(int id) SWIFT_NAME("init(_:)");

void doSomething();
} SWIFT_SHARED_REFERENCE(retainSharedObject, releaseSharedObject);
```

In this case, Swift will import the static `make` function as a Swift initializer:

```swift
let object = SharedObject(id: 42)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The id label shouldn't be there, i.e.,

Suggested change
let object = SharedObject(id: 42)
let object = SharedObject(42)

But I think you should give more examples here. Also, doSomething() isn't really necessary here.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@j-hui Let's add more examples of using the SWIFT_NAME technique in a follow-up patch. We can experiment with this feature on some adopter projects or dummy examples before documenting.

object.doSomething()
```

**Note**: If a C++ constructor and a user-annotated static factory (via `SWIFT_NAME`) have identical parameter signatures, Swift prefers the static factory when resolving initializer calls. Using `SWIFT_NAME("init(...)")` is especially useful if you want to use a custom allocator or you want to disable direct construction entirely and expose only factories.


### Inheritance and Virtual Member Functions

Similar to value types, casting an instance of a derived reference type to a
Expand Down