2
/// This file is part of Rheolef.
4
/// Copyright (C) 2000-2009 Pierre Saramito <Pierre.Saramito@imag.fr>
6
/// Rheolef is free software; you can redistribute it and/or modify
7
/// it under the terms of the GNU General Public License as published by
8
/// the Free Software Foundation; either version 2 of the License, or
9
/// (at your option) any later version.
11
/// Rheolef is distributed in the hope that it will be useful,
12
/// but WITHOUT ANY WARRANTY; without even the implied warranty of
13
/// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14
/// GNU General Public License for more details.
16
/// You should have received a copy of the GNU General Public License
17
/// along with Rheolef; if not, write to the Free Software
18
/// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
20
/// =========================================================================
21
// maquette for a hierarchy of classes: two concrete classes + 1 abstrct one
22
// the second concrete class has additionnal members
23
// the final object implements a fat interface: check whether we
24
// have the 2nd object before calling the extra members.
26
#include "rheolef/smart_pointer.h"
27
using namespace rheolef;
29
// --------------------------------------------------------------
30
// objects representation (could be file "object.h")
31
// --------------------------------------------------------------
32
class object_abstract_rep {
34
virtual object_abstract_rep* clone () const = 0;
35
virtual ~object_abstract_rep() {}
36
virtual int value () const = 0;
37
virtual void set_value (int i) = 0;
39
class object1_rep : public object_abstract_rep {
42
object1_rep (int i) : object_abstract_rep(), _i(i) {}
43
object_abstract_rep* clone () const {
44
warning_macro ("object1::clone: i="<<_i);
45
return new_macro(object1_rep(*this));
47
~object1_rep() { warning_macro ("object1::destroy: i="<<_i); }
48
int value () const { return _i; }
49
void set_value (int i) { _i = i; }
51
class object2_rep : public object_abstract_rep {
55
object2_rep (int i, string s) : object_abstract_rep(), _i(i), _name(s) {}
56
object_abstract_rep* clone () const {
57
warning_macro ("object2::clone: i="<<_i<<", name="<<_name);
58
return new_macro(object2_rep(*this));
60
~object2_rep() { warning_macro ("object2::destroy: i="<<_i<<", name="<<_name); }
61
int value () const { return _i; }
62
void set_value (int i) { _i = i; }
63
string name () const { return _name; }
64
void set_name (string s) { _name = s; }
66
// --------------------------------------------------------------
67
// object interface (fat interface, for object2)
68
// --------------------------------------------------------------
69
class object : public smart_pointer_clone<object_abstract_rep> {
70
typedef smart_pointer_clone<object_abstract_rep> base;
74
explicit object(int i) : base(new_macro(object1_rep(i))) {}
75
explicit object(int i, string s) : base(new_macro(object2_rep(i,s))) {}
77
// accessors & modifiers:
79
int value () const { return data().value(); }
80
void set_value (int i) { data().set_value (i); }
82
void set_name (string s);
84
// here are accessors specific to object2 representation
85
// => check whether we have an object2
89
const object_abstract_rep* abstract_ptr = base::pointer();
90
const object2_rep* ptr = dynamic_cast<const object2_rep*>(abstract_ptr);
91
check_macro (ptr != 0, "object is not an object2");
95
object::set_name(string s)
97
object_abstract_rep* abstract_ptr = base::pointer();
98
object2_rep* ptr = dynamic_cast<object2_rep*>(abstract_ptr);
99
check_macro (ptr != 0, "object is not an object2");
102
// --------------------------------------------------------------
104
// --------------------------------------------------------------
111
warning_macro ("A.count="<<A.reference_counter());
113
std::cout << "A.name = " << A.name() << std::endl;
114
std::cout << "B.name = " << B.name() << std::endl;
115
std::cout << "C.name = " << C.name() << std::endl;
116
check_macro (A.name() != B.name(), "It is not a true copy semantic");
117
check_macro (C.name() == B.name(), "It is not a true copy semantic");
118
std::cout << "It seems to be a true copy semantic." << std::endl;
119
warning_macro ("A.count="<<A.reference_counter());
120
warning_macro ("B.count="<<B.reference_counter());
121
warning_macro ("C.count="<<C.reference_counter());