接口实现
An interface declares an empty virtual class. The actual functionality must be defined in an implementation. For a given interface multiple implementations can exist. Such an implementation is called a component .
An implementation can be defined in any source code file of a module/plugin. This way it is possible to publish the interface header file and to keep the implementation private.
A simple interface is defined as:
// This example shows the declaration of a simple interface.// --------------------------------------------------------------------- // Simple class that stores a maxon::Int number. // --------------------------------------------------------------------- class SimpleClassInterface : MAXON_INTERFACE_BASES (maxon::ObjectInterface) { MAXON_INTERFACE (SimpleClassInterface, MAXON_REFERENCE_NORMAL , "net.maxonexample.interfaces.simpleclass" );
// --------------------------------------------------------------------- // Returns the stored number. // --------------------------------------------------------------------- MAXON_METHOD maxon::Int GetNumber() const ; };
// This interface is declared in a file named "simpleclass.h". The automatically // generated files are therefore named "simpleclass1.hxx" and "simpleclass2.hxx"
// The .hxx header files define the reference class "SimpleClassRef".
#include "simpleclass1.hxx"// declare the published objects "SomeSimpleClass" and "OtherSimpleClass" // that give access to implementations of SimpleClassInterface
// the declaration must be placed between the two hxx files since "SimpleClassRef" is defined in the first hxx file
A simple implementation of that interface can look like this:
// This example shows the implementation of a simple interface.// This class implements SimpleClassInterface. class SimpleClassImplementation : public maxon::Component <SimpleClassImplementation, SimpleClassInterface> { MAXON_COMPONENT (); public : // implementation of interface methods MAXON_METHOD void SetNumber( maxon::Int number) { _value = number; } MAXON_METHOD maxon::Int GetNumber() const { return _value; }
// private data only available inside the implementation private : maxon::Int _value = 1; };
A new component must be registered to inform Cinema 4D about it. The registration defines the ID which can be used to access the component class which in return can be used to create instances. The ID is created by combining the reverse domain name and the implementation class name.
It is also possible to expose a given component as a published object that was declared with MAXON_DECLARATION :
// This example registers the component and publishes it as the published object "SomeSimpleClass". // The published object must be declared in a header file. MAXON_COMPONENT_CLASS_REGISTER (OtherClassImplementation, SomeSimpleClass);This published object is used like this:
// This example creates a reference class from a component // registered at the given declaration.// create reference // The "SomeSimpleClass" published object is declared in a header file. // The obtained component is used to create a new instance using Create(). const SimpleClassRef simpleClass = SomeSimpleClass().Create() iferr_return ;
// use reference simpleClass.SetNumber(456); const maxon::Int number = simpleClass.GetNumber(); DiagnosticOutput ( "Number: @" , number);
MAXON_COMPONENT_OBJECT_REGISTER is used to create an instance of the component class and to publish that object:
// This example registers the given implementation, creates an instance of the class // and makes that object available with the given published object "OtherSimpleClass". MAXON_COMPONENT_OBJECT_REGISTER (ThirdSimpleClassImplementation, OtherSimpleClass);The object published this way can be obtained like this:
// This example shows how to access an object created // and registered with MAXON_COMPONENT_OBJECT_REGISTER. MAXON_SCOPE { // access object crated with MAXON_COMPONENT_OBJECT_REGISTER const SimpleClassRef& simpleClass = OtherSimpleClass(); const maxon::Int number = simpleClass.GetNumber(); DiagnosticOutput ( "Number: @" , number); } MAXON_SCOPE { // create copy of the object created with MAXON_COMPONENT_OBJECT_REGISTER const SimpleClassRef simpleClass = OtherSimpleClass();// use reference simpleClass.SetNumber(789); const maxon::Int number = simpleClass.GetNumber(); DiagnosticOutput ( "Number: @" , number); }
The attribute MAXON_COMPONENT() declares a given class as a component. The attribute can be used to define the component type:
Additionally, MAXON_COMPONENT() can define additional components that are added to a given component. If this is not sufficient one can implement maxon::ComponentRoot::ConfigureClass(). These additional components typically implement the interface's base interfaces. See Interface Inheritance .
Every component can implement these default functions. They are declared in the maxon::ComponentRoot class.
InitImplementation()
is called before the
Cinema 4D
core is loaded. This means that no classic API code can be called in this context.
Static methods of interfaces can only be implemented once. The implementation class of these methods must be additionally registered with MAXON_STATIC_REGISTER() .