Author: Stephan Bergmann. Last changed: $Date: 2004/10/28 13:05:15 $.
salhelper
/cppuhelper
APIThe following list gives instructions how to design a C++ class that shall be
part of the API of either salhelper
or cppuhelper
(i.e., of any SDK shared library that has a C++ API that is not all-inline).
The motivating force behind those instructions is to minimize the amount of
global symbols (especially weak ones). The list also explains exactly which
symbols corresponding to a class to export on which platform; see
SDK
Dynamic Library Versioning for details about adding exported symbols
to dynamic libraries.
Never define inline functions. (Neither explicitly nor implicitly, by defining a function within its class. Inline functions, especially constructors and destructors, often make it necessary to export certain symbols that could otherwise be left unexported.)
Make sure that the compiler does not declare any implicit functions. (To avoid any implicitly defined inline functions, see point 1. Potential implicit functions are default constructors, copy constructors, destructors, and copy assignment operators. The easiest way to avoid them is to declare a destructor, at least one copy constructor, and at least one copy assignment operator for each class; those declared functions that shall not be available can be declared private and left undefined.)
Define every destructor that is declared. (Even a destructor that is declared pure virtual, to avoid any implicitly defined inline functions, see point 1.)
If a class type (possibly cv-qualified, and possibly nested within pointer or reference types) is ever used either
dynamic_cast
expression that
needs to be evaluated at runtime,dynamic_cast
expression that needs to be evaluated at
runtime,typeid
expression,typeid
expression,throw
expression, orcatch
handler,then declare its destructor virtual. (To have a dedicated place where RTTI for that class is generated. Since in general you cannot control the ways a class is used, the best advice probably is to do this for each class that is intended to be either used as an exception or subclassed.)
If the destructor of a class is declared virtual, declare the destructors of all its base classes virtual. (To have a dedicated place where RTTI for the base classes is generated, which is referenced by the RTTI for the derived class. Since in general you cannot control the ways a class is used, the best advice probably is to do this for each class that is intended to be subclassed.)
Special symbols to be exported for GCC 3:
C1
and C2
variant symbols.D0
, D1
, and
D2
variant symbols. (The D0
variant seems to be
never called directly, but only be referenced from the vtable, but that is
no guarantee that this will not change in a future GCC version.)_ZTI
and _ZTS
symbols. (Strictly
speaking, the _ZTS
symbol need only be exported if the type is
ever used as an incomplete type.)rtl::MalformedUriException
; specifically
not affected are the standard exception classes
std::bad_alloc
, std::bad_cast
,
std::bad_exception
, std::bad_typeid
,
std::domain_error
, std::exception
,
std::invalid_argument
, std::ios_base::failure
,
std::length_error
, std::logic_error
,
std::out_of_range
, std::overflow_error
,
std::range_error
, std::runtime_error
, and
std::underflow_error
, as they all have dedicated places for
their RTTI symbols in libstlport_gcc.so
or
libstdc++.so.5
). To make those uses work under GCC 3, all
involved load objects have to bind the same definitions of those symbols at
runtime. To achieve this, the OOo build environment enforces that
all global _ZTI
and _ZTS
symbols defined
within a load object (as either weak or normal symbols) are indeed exported
(with version GCC_3_0_0
, in case the respective load object
uses symbol versioning). This implies that any _ZTI
and
_ZTS
symbols covered by the previous point are always exported
with version GCC_3_0_0
, which defeats the correct use of
versioning for those symbols.Special symbols to be exported for Sun C++ 5:
#Nvariant 1
variant symbols.#Nvariant 1
variant
symbols.__RTTI__
symbols (of which there are three, one
for the class itself, one for an unqualified pointer to the class, and one
for a const
-qualified pointer to the class).Special symbols to be exported for Microsoft Visual C++:
`scalar deleting
destructor'
or `vector deleting destructor'
symbols).