chip@ateng.UUCP (Chip Salzenberg) (03/29/88)
Several people have griped because they cannot provide access to member variables and also have the compiler automatically call a user-written routine when the value is modified. Actually, it's quite easy. Don't return a "foo&", just create a class whose only purpose in life is to be a "foo imposter". Here is an example that demonstrates the technique. (Be warned, I haven't compiled this; but I have used the technique before.) ================ BEGIN EXAMPLE ================== // temp conversion routines extern float ftoc(float); // F --> C extern float ctof(float); // C --> F // A general (F/C) temperature. class CelsiusImp; class FahrImp; class Temp { float celsius; // None of this Imperial junk :-) public: Temp() { celsius = 0.0; } CelsiusImp celsius(); // See below FahrImp fahr(); // See below }; // A Celsius "view" of a general temperature class CelsiusImp { Temp* temp; public: CelsiusImp(Temp* t) { temp = t; } // The magic: operator float () { return temp->celsius; } float operator = (float f) { return (temp->celsius = f); } }; // A Fahrenheight "view" of a general temperature class FahrImp { Temp* temp; public: FahrImp(Temp* t) { temp = t; } // The magic: operator float () { return ctof(t->celsius); } float operator = (float f) { return (t->celsius = ftoc(f)); } }; // Circular class references force me to put these functions last. CelsiusImp Temp::celsius() { return CelsiusImp(this); } FahrImp Temp::fahr() { return FahrImp(this); } ================ END EXAMPLE ================== So there you have it: now you can write Temp t; t.fahr() = 212; // call FahrInp::operator=() cout << "Water boils at " << t.celsius() << "degrees C\n"; and you can put whatever code you want into the operator=() functions. Now stop complaining and write those programs. :-) -- Chip Salzenberg "chip@ateng.UU.NET" or "codas!ateng!chip" A T Engineering My employer's opinions are a trade secret. "Anything that works is better than anything that doesn't."