 |
C++Talk.NET C++ language newsgroups
|
| View previous topic :: View next topic |
| Author |
Message |
Jonas Latt Guest
|
Posted: Fri Sep 24, 2004 11:29 am Post subject: Design question: class with reference semantics |
|
|
Dear all
In this mailing, I would like to ask other programmers for their opinion
on a design choice for a C++ class.
I am working on a library implementing a Matrix (or Array) type that
fullfills specific scientific purposes. The copy constructor and the
assignment operator have reference semantics. This means that the newly
created or assigned to matrix points to the same data as the old one
instead of copying them. The memory management is done through a
reference count, in the same manner as it is provided by the
boost::shared_ptr class.
This design makes the Matrix class act somewhat like a garbage-collected
Java class. The advantage is that a Matrix (which in a typical
application uses a big amount of memory) can be passed to and returned
from funtions more efficiently than if it were based on value semantics.
In particular, a Matrix can be efficiently stored in a STL container
without the need for further encapsulation in a boost::shared_ptr or any
other trick.
Still, I am concerned by two design issues for this class:
1. The semantics of the class make that it ressembles more a Java class
than a traditional C++ one. I wonder if this could be felt unusual by a
typical programmer and make his/her code more error-prone.
2. The reference semantics seem to be in conflict with the concept of
"const"-methods and -objects in C++. Indeed, in order to strictly
respect constness rules, I have the feeling that the copy-constructor
and assignment operator must take a non-const argument, which is quite
restrictive. Does anybody have an idea how this problem could be
elegantly solved? I understand that this is a question that has already
been touched upon by other library designers. This is for example the
case for the Array class the Blitz++ library. I am however not totally
sastisfied by the solution proposed there, as for example the copy
constructor and the assignment operator implement different semantics.
In any way, I appreciate very much any opinion on my question.
Cheers
/Jonas
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
|
|
| Back to top |
|
 |
Brooks Moses Guest
|
Posted: Sat Sep 25, 2004 6:12 pm Post subject: Re: Design question: class with reference semantics |
|
|
Jonas Latt wrote:
| Quote: | I am working on a library implementing a Matrix (or Array) type that
fullfills specific scientific purposes. The copy constructor and the
assignment operator have reference semantics. This means that the newly
created or assigned to matrix points to the same data as the old one
instead of copying them. The memory management is done through a
reference count, in the same manner as it is provided by the
boost::shared_ptr class.
|
It sounds like you are reinventing the wheel; NIST's "Template Numerical
Toolkit" pretty much fits this description, and it's available as public
domain. See http://math.nist.gov/tnt/index.html. It's not a very
complicated class, so I suspect it would also be fairly easy to adapt it
to your needs rather than reinventing all the reference-count parts.
It also certainly provides evidence that at least some programmers don't
find the reference semantics to be problematic.
- Brooks
--
The "bmoses-nospam" address is valid; no unmunging needed.
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
|
|
| Back to top |
|
 |
jakacki Guest
|
Posted: Mon Sep 27, 2004 10:36 am Post subject: Re: Design question: class with reference semantics |
|
|
| Quote: | 2. The reference semantics seem to be in conflict with the
concept of "const"-methods and -objects in C++. Indeed, in
order to strictly respect constness rules, I have the
feeling
that the copy-constructor and assignment operator must
take a
non-const argument, which is quite restrictive.
|
Why do you think so?
BR
Grzegorz
--
Free C++ frontend library: http://opencxx.sourceforge.net
Sender of this e-mail: http://www.dziupla.net/gj/cv
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
|
|
| Back to top |
|
 |
Jonas Latt Guest
|
Posted: Mon Sep 27, 2004 8:20 pm Post subject: Re: Design question: class with reference semantics |
|
|
| Quote: | 2. The reference semantics seem to be in conflict with the
concept of "const"-methods and -objects in C++. Indeed, in
order to strictly respect constness rules, I have the
feeling
that the copy-constructor and assignment operator must
take a
non-const argument, which is quite restrictive.
Why do you think so?
|
The problem, as far as I understand it, is as follows:
Suppose that a ``Matrix'' class is copy constructed from another,
constant, Matrix class:
Matrix::Matrix(const Matrix& rhs);
Then we can copy construct a non-constant Matrix from a constant one:
const Matrix a;
Matrix b(a);
Because of the reference semantics of copy construction, a and b now
point to the same data. Thus, data that are declared constant by Matrix
a can be modified through Matrix b. This I feel being a violation of
constness rules.
Regards, Jonas
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
|
|
| Back to top |
|
 |
Tony Delroy Guest
|
Posted: Mon Sep 27, 2004 9:17 pm Post subject: Re: Design question: class with reference semantics |
|
|
| Quote: | 2. The reference semantics seem to be in conflict with the concept of
"const"-methods and -objects in C++. Indeed, in order to strictly
respect constness rules, I have the feeling that the copy-constructor
and assignment operator must take a non-const argument, which is quite
restrictive. Does anybody have an idea how this problem could be
elegantly solved? I understand that this is a question that has already
|
Mutable data members (such as reference counters) can address this issue. - Tony
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
|
|
| Back to top |
|
 |
jakacki Guest
|
Posted: Tue Sep 28, 2004 10:16 am Post subject: Re: Design question: class with reference semantics |
|
|
| Quote: | Suppose that a `Matrix'' class is copy constructed from
another, constant, Matrix class:
Matrix::Matrix(const Matrix& rhs);
Then we can copy construct a non-constant Matrix from a
constant one:
const Matrix a;
Matrix b(a);
Because of the reference semantics of copy construction,
a and b now point to the same data. Thus, data that are
declared constant by Matrix a can be modified through
Matrix b. This I feel being a violation of constness
rules.
|
Your design uses Proxy pattern: Matrix is a proxy enabling
access to a resource.
Perhaps your problem stems from the failure to distinguish
the constness of a proxy from the constness of a resource.
Raw pointers are also instances of Proxy pattern and it
may help to see the distinction for raw pointers:
const Foo * cr; // const resource, mutable proxy
Foo const * cr; // same as above
Foo * const cp; // mutable resource, const proxy
Observe, that it is OK to call 'cp->ModifyObject()',
because type of 'cp' promises that the *proxy*, not the
resource, will not be modified trough 'cp'. OTOH
'cr->ModifyObject()' will fail to compile.
In your example
const Matrix a; // mutable resource, const proxy
Matrix b(a); // mutable resource, mutable proxy
you say nothing about constness of resources.
To express the constness of a resource, I would suggest the
following design:
class ConstMatrix
{
public:
// ...
ConstMatrix(const ConstMatrix& that)
: refCount_(that.refCount_)
, data_(that.data_)
{
++*refCount_;
}
// only non-mutating accesors
double Get(int i, int j) const
{
return data_->Get(i,j);
}
private:
int* refCount_;
protected:
Data* data_;
};
class Matrix : public ConstMatrix
{
// ...
Matrix(const Matrix& that)
: ConstMatrix(that)
{}
// mutating accessors
void Set(int i, int j, double v) const
{
data_->Set(i,j,d);
}
};
BR
Grzegorz
PS: Some people will advise against protected data members,
as this lowers the encapsulation of a base class
against derived classes. I think this is not a problem
here, because Matrix and MatrixConstant are not
designed to be derived from by clients. Unfortunately I
don't know any way of expressing this constraint in C++
that would be applicable in this design.
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
|
|
| Back to top |
|
 |
Jonas Latt Guest
|
Posted: Wed Sep 29, 2004 9:38 am Post subject: Re: Design question: class with reference semantics |
|
|
| Quote: | In your example
const Matrix a; // mutable resource, const proxy
Matrix b(a); // mutable resource, mutable proxy
you say nothing about constness of resources.
To express the constness of a resource, I would suggest the
following design:
class ConstMatrix
{
public:
// ...
|
Thank you for this very clear answer. This, indeed, is the point I could
not come up with by myself: declaring both a const and a non-const
version of Matrix.
/Jonas
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
|
|
| Back to top |
|
 |
|
|
You cannot post new topics in this forum You cannot reply to topics in this forum You cannot edit your posts in this forum You cannot delete your posts in this forum You cannot vote in polls in this forum
|
|