|
Boost : |
From: Reece Dunn (msclrhd_at_[hidden])
Date: 2004-01-06 17:46:43
Dan W. wrote:
>//invariants_test.cpp
>#include "invariants.hpp"
>
>using namespace boost::DBC;
>
>class my_class INVARIANT_DERIVED
>{
> int a, b;
> void verify_invariants() const
> {
> ENSURE( a + b == 5 );
> }
> public:
> my_class() : a(2), b(3)
> {
> FIRST_INVARIANT_CHECK
> }
> ~my_class()
> {
> LAST_INVARIANT_CHECK
> }
> void f() //public, non-const: must check
> {
> INVARIANT_CHECKED
> ++a; --b;
> } //ok
> void g() //public, non-const: must check
> {
> INVARIANT_CHECKED
> ++a;
> } //boom!
>};
>
>int main()
>{
> my_class my_obj;
> my_obj.f();
> my_obj.g();
> return 0;
>}
What about this?:
class derived: public my_class //, public invariants // [1]
{
private:
int c;
void verify_invariants() const
{
ENSURE( c > 0 ); // [4]
my_class::verify_invariants(); // required! // [2]
}
pulbic:
derived( int _c ): c( _c )
{
// FIRST_INVARIANT_CHECK // [3]
}
};
[1] Not needed because we know that it derives from invariants.
[2] Needed to ensure my_class invariants hold
[3] Not needed -- initiated in my_class
Q: How does this affect the validity of [4] - doesn't the compiler call
the my_class constructor before setting the value of c -- BOOM!
Or, how about this example?
class base1: public invariants { ... }; // implements verify_invariants
class base2: public invariants { ... }; // implements verify_invariants
class derived: public base1, public base2
{
};
If I implement verify_invariants in derived, I'd need to do it thus:
void verify_invariants() const
{
base1::verify_invariants();
base2::verify_invariants();
}
to make it work correctly. If I don't, the compiler will complain about
verify_invariants being ambiguous.
If you have a complex MI framework with thousands of classes, managing the
code would become very difficult. As such, I am now of the feeling that a
language extension would be best (i.e. the compiler can deduce the correct
code). Thus, you could have something like (depending on what the C++0x
invariant proposal looks like):
class my_class
{
private:
int a;
int b;
__invariant( a + b == 5 );
public:
void set( int _a, int _b )
{
__precondition( _a > 0 );
}
};
And can add a check for invariant capabilities thus:
#if COMPILER_SUPPORTS_DBC
# define BOOST_INVARIANT(x) __invariant(x)
#else
# define BOOST_INVARIANT(x)
#endif
or something similar.
Regards,
Reece
_________________________________________________________________
Express yourself with cool new emoticons http://www.msn.co.uk/specials/myemo
Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk