[comp.lang.c++] Transparent int class

matthew@hydra.ua.oz.au (Matthew Donaldson) (10/15/90)

I am not sure that this can be done in C++, but I am trying to make a
class that looks exactly like an int (or as much so as possible), but
inside works differently.  I want an integer that is protected against
concurrent reads and writes, but still looks like an int.  So each
operation would use mutual exclusion primitives to protect against concurrent
assignment, etc.

The aim is to be able to do something like this:

ProtectedInt a;

...

a= 2;


cout << "Now a is " << a << "\n";

and everything else you can do with ints, such as

a |= 2,  fn(a),  int b= a,  ProtectedInt b=a, etc.
[ as an aside, how are operations like |= handled?  There is no operator|= ]

I can do most of these - the main exception is the actual using of the class
to return an int - that is, just using the "a" variable, and making it look
like an int.  I haven't found any way of doing this, and have had to be
content with a.Value() or whatever, but this spoils the look of things a bit.
Does anyone know if it is possible to do this, and if so how?

Also, is there a more general solution to the whole problem, rather than
having to define every operator for the class to perform operations on ints.

		-Matthew

--
-------
Matthew Donaldson
matthew@cs.ua.oz.au
Operating Systems Group
Computer Science Department
University of Adelaide

vaughan@mcc.com (Paul Vaughan) (10/16/90)

   I am not sure that this can be done in C++, but I am trying to make a
   class that looks exactly like an int (or as much so as possible), but
   inside works differently.  I want an integer that is protected against
   concurrent reads and writes, but still looks like an int.  So each
   operation would use mutual exclusion primitives to protect against concurrent
   assignment, etc.

   The aim is to be able to do something like this:

   ProtectedInt a;

   ...

   a= 2;


   cout << "Now a is " << a << "\n";

   and everything else you can do with ints, such as

   a |= 2,  fn(a),  int b= a,  ProtectedInt b=a, etc.
   [ as an aside, how are operations like |= handled?  There is no operator|= ]

   I can do most of these - the main exception is the actual using of the class
   to return an int - that is, just using the "a" variable, and making it look
   like an int.  I haven't found any way of doing this, and have had to be
   content with a.Value() or whatever, but this spoils the look of things a bit.
   Does anyone know if it is possible to do this, and if so how?

   Also, is there a more general solution to the whole problem, rather than
   having to define every operator for the class to perform operations on ints.

By providing a constructor, conversion operator, assignment operators
(the whole suite), and copy constructor, you can come pretty close to
an integer look-alike.  For instance,

class Int {
public:
  Int(int);
  Int(Int&);
  operator =(int);
  operator int();
  operator +=(int);
  operator |=(int);

private:
  int i;
};



main() {
  Int i(3);
  i = 2;
  i += 3;
  i |= 4;
  int j = i;
}

compiles with cfront 2.0 and g++.  I don't believe there is any way to
get around having to define all the possible assignment operators (and
there are quite a few for int's).  Also, Int can't be made to behave
*exactly* like ints because of the conversion rules--because it goes
through an extra layer of conversion, there will be some differences
when multiple conversions are required.

 Paul Vaughan, MCC CAD Program | ARPA: vaughan@mcc.com | Phone: [512] 338-3639
 Box 200195, Austin, TX 78720  | UUCP: ...!cs.utexas.edu!milano!cadillac!vaughan

jimad@microsoft.UUCP (Jim ADCOCK) (10/18/90)

In article <MATTHEW.90Oct15185053@hydra.ua.oz.au> matthew@hydra.ua.oz.au (Matthew Donaldson) writes:
>I am not sure that this can be done in C++, but I am trying to make a
>class that looks exactly like an int (or as much so as possible), but
>inside works differently....

See Hansen "The C++ Answer Book" pg 252 for the "right" way to implement
an "Int" class.  [Many other sources I've read get this "wrong."]

zmls04@trc.amoco.com (Martin L. Smith) (10/19/90)

In article <MATTHEW.90Oct15185053@hydra.ua.oz.au> matthew@hydra.ua.oz.au (Matthew Donaldson) writes:

   I am not sure that this can be done in C++, but I am trying to make a
   class that looks exactly like an int (or as much so as possible), but
   inside works differently.  I want an integer that is protected against
   concurrent reads and writes, but still looks like an int.  So each
   operation would use mutual exclusion primitives to protect against concurrent
   assignment, etc.

   The aim is to be able to do something like this:

   ProtectedInt a;

   ...

   a= 2;


   cout << "Now a is " << a << "\n";

   and everything else you can do with ints, such as

   a |= 2,  fn(a),  int b= a,  ProtectedInt b=a, etc.
   [ as an aside, how are operations like |= handled?  There is no operator|= ]

   I can do most of these - the main exception is the actual using of the class
   to return an int - that is, just using the "a" variable, and making it look
   like an int.  I haven't found any way of doing this, and have had to be
   content with a.Value() or whatever, but this spoils the look of things a bit.
   Does anyone know if it is possible to do this, and if so how?

   Also, is there a more general solution to the whole problem, rather than
   having to define every operator for the class to perform operations on ints.

------------------------------------------------------------

We've run into the same problem and, to us, it is the most serious
(apparent) structural limitation in providing well-packaged user-defined
data types in C++.  Is there a clean, general solution?
--

   Martin L. Smith             Amoco Research Center
                               P.O. Box 3385
 zmls04@trc.amoco.com          Tulsa, OK 74102
[zmls04@sc.msc.umn.edu]        918-660-4065

saustin@bbn.com (Steve Austin) (10/19/90)

zmls04@trc.amoco.com (Martin L. Smith) writes:

>In article <MATTHEW.90Oct15185053@hydra.ua.oz.au> matthew@hydra.ua.oz.au (Matthew Donaldson) writes:


>   The aim is to be able to do something like this:

>   ProtectedInt a;
>   ...
>   a= 2;
>   cout << "Now a is " << a << "\n";

>   and everything else you can do with ints, such as

>   a |= 2,  fn(a),  int b= a,  ProtectedInt b=a, etc.
>   [ as an aside, how are operations like |= handled?  There is no operator|= ]

>   Also, is there a more general solution to the whole problem, rather than
>   having to define every operator for the class to perform operations on ints.

>We've run into the same problem and, to us, it is the most serious
>(apparent) structural limitation in providing well-packaged user-defined
>data types in C++.  Is there a clean, general solution?

I may be missing something here, but by providing cast operators to and from
the new form of int's (called here pint's) you can get the usual integer
operators do most of the work and just define the operations that you want
to define. The program below shows how simple the definition can be - I could
add specific operators, such as "pint operator *(pint, pint)" to redefine
a multiplication which (eg) check for possible overflow.

Hope this helps

	Steve Austin
-------------------------------------------------------------------------------

	loki:tmp> cat pint.cc
	#include        <stdlib.h>

	class   pint
	{
		int     value;
	public:
		pint(int i = 0) { value = i; };
		operator int() { return value; };
	};

	main()
	{
		pint    a = 4;
		pint    b(3);
		pint    c = a+b;
		pint    d(c+2);

		printf("%d %d\n", int(c), int(d-2));
		c = 2;
		c |= a;         // there *is* an opeator |=
		printf("%d\n", int(c));

		exit(0);
	}
	loki:tmp> g++ -o pint pint.cc
	loki:tmp> ./pint
	7 7
	6
	loki:tmp> exit