RTI Connext Modern C++ API Version 7.3.0
|
Basic concepts required to use the API correctly.
Basic concepts required to use the API correctly.
There are a few basic conventions that you need to understand to use this API correctly:
All types in the API are value types, reference types, or move-only types. In this documentation a type is a value type, unless explicitly marked with <<reference-type>> or <<move-only-type>>. In some cases the type may be marked with <<value-type>> for clarity.
<<value-type>> Value types implement value semantics.
Note that in this API, types that don't specify their type semantics are value types by default. IDL-generated types are also value types.
Value types provide the following functionality:
swap()
function.Those operations are not documented for each type unless they deviate from their usual behavior.
<<reference-type>> Reference types implement reference semantics.
In a reference type copy operations, such as copy-construction and copy-assignment
are shallow. The reference types are modeled after shared pointers. Similar to pointers, it is important to distinguish between an entity and a reference (or handle) to it. A single entity may have multiple references. Copying a reference does not copy the entity it is referring to—creating additional references from the existing reference(s) is a relatively inexpensive operation.
The lifecycle of references and the entity they are referring to is not the same. In general, the entity lives as long as there is at least one reference to it. When the last reference to the entity ceases to exists, the entity it is referring to is destroyed.
However, there are some exceptions. It is possible—and often convenient—to retain an entity even though it has no references, for example to look it up later. An reference can also be explicitly closed, deleting the object it references, regardless of the existence of other references.
An entity is considered to still be in use (i.e., retained) if any of the following conditions are met:
retain()
member function.Topic
exist, its related DomainParticipant
won't be deleted.std::shared_ptr<Listener>
. When a shared_ptr
is used, the entity is not retained.)All reference types inherit from dds::core::Reference
. The reference semantics are implemented using a shared count.
Reference types provide the following functionality:
Constructors specific to the type
Creates a new object and a reference to it. For example:
Copy constructor
Creates a new reference to an existing object, increasing the reference count. For example:
Assignment operator
Replaces the object that was referenced to with a new one, possibly decreasing the reference count of the former object and increasing it for the new one.
Constructor from dds::core::null
(or nullptr
<<C++11>>)
Creates an instance that doesn't reference any object. For example:
Assignment operator from dds::core::null
(or nullptr
<<C++11>>)
Makes the reference empty, decreasing the reference count.
Equal operator (to another reference)
Returns true only if the referenced object is the same. For example:
The operators <
, <=
, >
, >=
are also supported, and compare the underlying pointer.
Equal operator to dds::core::null
(or nullptr
<<C++11>>)
Returns true only if this reference is empty. For example:
Some reference types, including dds::core::Entity and its subclasses, also provide:
Forces the destruction of the underlying object. After this, calling a method on the destroyed object throws dds::core::AlreadyClosedError
. For example:
retain()
Disables the destruction of the underlying object. When all references are destroyed the underlying object still exists and can be looked up. To finally destroy a retained object you need to explicitly call close().
For example:
Reference types with an inheritance relationship such as dds::core::Entity or dds::core::cond::Condition can use dds::core::polymorphic_cast to cast from a base to a derived class.
For more examples on reference types see Entity Use Cases
<<move-only-type>> Move-only types are types that can't be copied, only "moved." A move-only type encapsulates a view of an internal resource. Only one reference to that resource may exist at a time.
<<C++11>> Functionality supported only in C++11.
This API is designed to integrate with and make use of C++11. The API headers are prepared to detect at application-compile time what C++11 features are available and make use of them.
Different compilers support different C++11 features, and some require
explicitly activating C++11 support. If your compiler activates C++11 by default (for example, Visual Studio 2010 and later), you don’t need to do anything. Whatever features are available will be used. If your compiler requires an explicit activation, you will need to pass a flag (for example, -std=c++0x or -std=c++11 in gcc and clang). The Platform Notes can help with that.
The API provides the following C++11 features when available:
dds::sub::LoanedSamples
.dds::sub::cond::ReadCondition
noexcept
, like move constructors.std::initializer_list
in several functions. For example see rti::core::policy::Property
. <<extension>>dds::core::xtypes::DynamicType
and dds::core::xtypes::DynamicData
using tuples. <<extension>> <<experimental>>std::chrono::duration
and dds::core::Duration
. <<extension>>nullptr
and dds::core::null
.The modern C++ API uses exceptions to report errors.
If a function doesn't document what exceptions it may throw and is not declared noexcept
, then it may throw any of the standard exceptions.
Destructors won't throw exceptions. There are cases however where you may need to handle an error during an object destruction. Some classes, like the reference types provide a close() operation–which can throw–that destroys the underlying entity.
Note that the API can also throw C++ standard exceptions such as std::bad_alloc
.
For a few critical operations both a regular exception-throwing function and a noexcept function are provided. The noexcept versions always return an rti::core::Result object, and are always extension functions that need to be accessed with the ->
operator. For example, a dds::sub::DataReader provides both take()
and take_noexcept()
:
<<extension>> The stereotype <<extension>> indicates that a type or a function is RTI Connext product extension to the standard DDS specification.
The RTI extension APIs complement the standard APIs specified by the OMG DDS specification.
There are the following kinds of extensions: extension methods for a standard class, extension types, and extension standalone functions.
To call an extension methods for an standard class use the extensions()
method or the overloaded arrow operator (->
). For example:
Note that the arrow operator is noexcept
but the extensions()
method of a reference type is not (it may throw dds::core::NullReferenceError if the object is dds::core::null).
In this documentation extension members in a standard type appear as members of that type, although they are members of a delegate type called through the standard type (calling extensions()
or the arrow operator). We omit this implementation detail from the API documentation for simplicity.
Extension types reside in the rti
namespace instead of the dds
namespace. For example:
The following example combines an extension function for a standard type (Reliability
) and an extension type (AcknowledgmentKind
):
Extension standalone functions are also in the rti
namespace. For example:
<<experimental>> Experimental features subject to change.
Some times the parameter may have one of the following stereotypes, but in most cases the function signature reveals if the parameter is an input parameter (by value or const-reference), or output parameter (non-const reference).