2005/5/10

     
 

Method Types

artefaktur

| Basic Types | Enum Types | Object Types | Array Types | Interface Types | Exception Types | Member Types | Method Types | Namespace Types | Foreign Types |



Methods are function bound to a ACDK interface or class.


Content of this chapter:

   method types
     pure virtual methods
     virtual methods
     non virtual methods
     static methods
   Arguments
     Default argument passing
     Direction declaration IN, OUT, INOUT
       IN Parameter
       OUT Parameter
       INOUT Parameter
     BYVAL / BYREF parameters
       BYVALIN
       BYVALOUT
       BYVALINOUT
   Exception declaration
     Return values



 method types

 pure virtual methods

Inteface methods, which has to overwritten by the derived classes are pure virtual:

class LegalAcdkClass
: extends acdk::lang::Object
{
public:
  virtual void method() = 0;
};

 virtual methods


  // ...
  virtual void method();

 non virtual methods


  // ...
  void method();

 static methods


  // ...
  static void method();

 Arguments

 Default argument passing

The default argument passing in ACDK methods is:
  • basic types (int, float, char, etc.) by value
  • enum by value
  • classes and interfaces by reference ('R'-objects)
  • arrays by reference (is also a 'R'-object)

 Direction declaration IN, OUT, INOUT

IDL languages used by DCOM and CORBA supports enhanced parameter declarations:

 IN Parameter

The parameter will be passed from the caller to the callee.
This is also the default behaviour if the parameter has not passing tag.

For performance reason it is recomented to tag all Object IN parameter with IN attribute.


  // ...
  void foo(IN(RStringBuffer) buffer, int len)
  {
    buffer = new StringBuffer(); // caller not be effected, RStringBuffer isn't changed
    buffer->append("asdf"); // caller be effected. 
    len = 42; // caller not be effected
  }
  // is equivalent to
  //void foo(RStringBuffer buffer, int len);
  void use_foo()
  {
    RStringBuffer sb = new StringBuffer("");
    RStringBuffer sbs = sb;
    int value = 1000;
    foo(sb, value);
    //value == 1000 && sb == sbs
    // sb->toString() == "ACDK"
  }

If an parameter has no or IN tag, the parameter can also passed as stack variable:

  // ...
  void foo(IN(RStringBuffer) sb)
  {
  }
  void use_foo()
  {
    StringBuffer sb(100); // on stack
    foo(&sb); // legal for none, IN and BYVAL
  }

 OUT Parameter

The parameter will be passed from the caller:

  // ...
  void foo(OUT(RStringBuffer) buffer, OUT(int) len)
  {
    // buffer is unitialized here
    buffer = new StringBuffer(1024);
    // buffer is now initialed;
    buffer->append("ACDK");
    len = buffer->length();
  }
  RString use_foo()
  {
    RStringBuffer sb;
    int len;
    foo(sb, len);
    System::out->println("Buffer is [" + sb->toString() + "] len = " + len);
    return sb->toString();
  }
The OUT parameter behaviour may differs in different context:
if the foo() call is a local inprocess call the OUT parameter works the same like INOUT parameter - which means, the value given to foo(OUT(RStringBuffer), OUT(int) len) will be visible by foo() -, in distributed computing the parameter are unitialized.

!

You cannot pass stack object as OUT-Parameter.

 INOUT Parameter

An INOUT parameter is a combination of IN and OUT. A value will transfered from the caller to the callee and back.

  void redimStringBuffer(INOUT(RStringBuffer) sb, INOUT(int) size)
  {
    if (sb->capacity() > size)
      return;
    size += size % 1024;
    
    RStringBuffer newnsb = new StringBuffer(size);
    newnsb->append(sb->toString());
    sb = newsb;
  }
  void useRedimStringBuffer()
  {
    RStringBuffer sb = new StringBuffer("ACDK");
    int size = 1353;
    redimStringBuffer(sb, size);
    // sb changed
    // sb contains "ACDK"
    // size == 2048
  }

!

You cannot pass stack object as INOUT-Parameter.


 BYVAL / BYREF parameters

!

The BYVAL / BYREF will be evaluated only if used in context of method remoting. Calling a method locally with BYVAL argument, the values still will be transfered in the default way (by value for basic types and by reference for object types).

Objects normally passed by reference. The BYVAL parameter tag transfers the object by value. This means, the value will be copied. This works only for Objects which fullfills following conditions
  • Object supports serialization and
  • Object has metainfo

 BYVALIN

Value will be copied from caller to callee.


 BYVALOUT

The OUT paramter will be copied.

 BYVALINOUT

Will mostly has the same effect as normal parameter passing by reference, but the value will be copied twice.

 Exception declaration

A sample for exception declaration:


  // 
  RObject set(int index, IN(RObject) obj) THROWS1(RIndexOutOfBoundsException);
  // this will be expandet to on some platforms to
  RObject set(int index, IN(RObject) obj) throw( RIndexOutOfBoundsException, RThrowable );
  // some compiler doesn't support bugfree exception declarations, to it simply expands to:
  RObject set(int index, IN(RObject) obj);

Following important point has to be regarded:
  • In ACDK exceptions are used as reference type (like in Java), so the 'R'Class type has to be declared in the throw delcarations
  • In C++ the caller of a function, which declares possible thrown exception, are not forced to handle or declare them itself. But if an exception will thrown by a function, which are are not declared in throw() (if any) the process will normally terminate.
    For this reason the RThrowable - the base of all ACDK exception - will be declared at the end of the throw-list.

 Return values

Return values can also be tagged with IN or OUT attributes.

In both cases the method must not return references from stack, but only members of an class or static values.

class AClass
: extends acdk::lang::Object
{
public:
  RObject _instance;
  IN(RObject) foo()
  {
    RObject obj = new String("asdf");
    return obj; // !!!! Illegal
  }
  OUT(RObject) foo()
  {
    return _instance; // legal
  }
};

Tagging return values with the IN parameter only has performance effects in ACDK.

Return values, which are tagged with the OUT attribute will also return the value by reference in DMI. The caller of the method must ensure, that the returned value may not used longer, than the called class instance lifes.

In DMI client, where types must mapped and in all remote DMI server, return values must not be tagges as OUT value.

See also:  ACDK Pseudo Keywords.