Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.

Znav
nextC++ Mapping for Classes
prevC++ Mapping for Interfaces

On this page:

Table of Contents
maxLevel3

Basic C++ Mapping for Operations

...

Wiki Markup
{zcode:cpp}
NodePrx node = ...;             // Initialize proxy
string name = node?->name();     // Get name via RPC
{zcode}

The proxy handle overloads operator?-> to forward method calls to the underlying proxy class instance which, in turn, sends the operation invocation to the server, waits until the operation is complete, and then unmarshals the return value and returns it to the caller.

...

Wiki Markup
{zcode:cpp}
NodePrx node = ...;             // Initialize proxy
node?->name();                   // Useless, but no leak
{zcode}

This is true for all mapped Slice types: you can safely ignore the return value of an operation, no matter what its type — return values are always returned by value. If you ignore the return value, no memory leak occurs because the destructor of the returned value takes care of deallocating memory as needed.

Ztop

Normal and idempotent Operations in C++

...

Because idempotent affects an aspect of call dispatch, not interface, it makes sense for the mapping to be unaffected by the idempotent keyword.

Ztop

Passing Parameters in C++

...

Wiki Markup
{zcode:cpp}
ClientToServerPrx p = ...;              // Get proxy...

p?->op1(42, 3.14, true, "Hello world!"); // Pass simple literals

int i = 42;
float f = 3.14;
bool b = true;
string s = "Hello world!";
p?->op1(i, f, b, s);                     // Pass simple variables

NumberAndString ns = { 42, "The Answer" };
StringSeq ss;
ss.push_back("Hello world!");
StringTable st;
st[0] = ss;
p?->op2(ns, ss, st);                     // Pass complex variables

p?->op3(p);                              // Pass proxy
{zcode}

You can pass either literals or variables to the various operations. Because everything is passed by value or const reference, there are no memory-management issues to consider.

Ztop

Anchor
out
out

Out-Parameters in C++

...

Wiki Markup
{zcode:cpp}
ServerToClientPrx p = ...;      // Get proxy...

int i;
float f;
bool b;
string s;

p?->op1(i, f, b, s);
// i, f, b, and s contain updated values now

NumberAndString ns;
StringSeq ss;
StringTable st;

p?->op2(ns, ss, st);
// ns, ss, and st contain updated values now

p?->op3(p);
// p has changed now!
{zcode}

...

Anchor
final
final

It is worth having another look at the final call:

Wiki Markup
{zcode:cpp}
p?->op3(p);      // Weird, but well?defined
{zcode}

...

Wiki Markup
{zcode:cpp}
MatrixArithmeticPrx ma = ...;      // Get proxy...
Matrix m1 = ...;                   // Initialize one matrix
Matrix m2 = ...;                   // Initialize second matrix
ma?->squareAndCubeRoot(m1, m2, m1); // !!!
{zcode}

This code is technically legal, in the sense that no memory corruption or locking issues will arise, but it has surprising behavior: because the same variable m1 is passed as an input parameter as well as an output parameter, the final value of m1 is indeterminate — in particular, if client and server are collocated in the same address space, the implementation of the operation will overwrite parts of the input matrix m1 in the process of computing the result because the result is written to the same physical memory location as one of the inputs. In general, you should take care when passing the same variable as both an input and output parameter and only do so if the called operation guarantees to be well-behaved in this case.

Ztop

Chained Invocations in C++

...

Wiki Markup
{zcode:cpp}
p2?->setName(p1?->getName());
{zcode}

This works exactly as intended: the value returned by p1 is transferred to p2. There are no memory-management or exception safety issues with this code.

Ztop

Exception Handling in C++

...

Wiki Markup
{zcode:cpp}
ChildPrx child = ...;           // Get proxy...
try {
    child?->askToCleanUp();      // Give it a try...
} catch (const Tantrum& t) {
    cout << "The child says: " << t.reason << endl;
}
{zcode}

...

Wiki Markup
{zcode:cpp}
void run()
{
    ChildPrx child = ...;       // Get proxy...
    try {
        child?->askToCleanUp();  // Give it a try...
    } catch (const Tantrum& t) {
        cout << "The child says: " << t.reason << endl;

        child?->scold();         // Recover from error...
    }
    child?->praise();            // Give positive feedback...
}

int
main(int argc, char* argv[])
{
    int status = 1;
    try {
        // ...
        run();
        // ...
        status = 0;
    } catch (const Ice::Exception& e) {
        cerr << "Unexpected run?time error: " << e << endl;
    }
    // ...
    return status;
}
{zcode}

...

For efficiency reasons, you should always catch exceptions by const reference. This permits the compiler to avoid calling the exception's copy constructor (and, of course, prevents the exception from being sliced to a base type).

Ztop

Exceptions and Out-Parameters in C++

...

Info

This is done for reasons of efficiency: providing the strong exception guarantee would require more overhead than can be justified.

Ztop

Exceptions and Return Values in C++

For return values, C++ provides the guarantee that a variable receiving the return value of an operation will not be overwritten if an exception is thrown. (Of course, this guarantee holds only if you do not use the same variable as both an out-parameter and to receive the return value of an invocation).

Ztop

See Also

...

  1. Sutter, H. 1999. Exceptional C++: 47 Engineering Puzzles, Programming Problems, and Solutions. Reading, MA: Addison-Wesley.

Zret
Znav
nextC++ Mapping for Classes
prevC++ Mapping for Interfaces