CategoryRefactoring: A special case of ReplaceRecordWithDataClass, for CeePlusPlus.
However, you are changing from a POD type (PlainOldData) to a true class.
In other languages, yes. But in C++, no. A struct is a class, and that is the point of this page.
Is it a "good" class that follows best practices? No. So this page is just talking about the initial step of refactoring. Further refactoring should eventually follow...but it needn't be simultaneous with changing your mind that the struct should be a class. That's all.
EncapsulateField on members will usually require one or several constructors. Therefore: remember to specify proper copying semantics for the class: at least declare a private copy constructor and assignment operator. Consider whether a destructor is desirable. While a virtual destructor belongs to the RuleOfFour?(declare either all or none); a value class is seldom a good base class for inheritance.
Writing such accessors is lying. It leads you to think the data is really an object, while it is not the case. One should leave them public, until he finds a better abstraction for the data. And if it is data and not an object, I'd leave it a struct.
The big change in CeePlusPlus occurs not when you type "class" instead of "struct"; as mentioned above that only changes the default inheritance and access level from public to private.
The big change occurs when you do any of the following:
class Foo { private: Foo (const Foo &) {}; Foo &operator = (const Foo &) {}; }; // or in C++11 use class Bar { private: Bar (Bar const &) = delete; Bar (Bar &&) = delete; Bar & operator=(Bar const &) = delete; };
As regards disabling the copy constructor and assignment operator, wouldn't it be better to put:
class Foo { private: Foo (const Foo &); Foo &operator = (const Foo &); };i. e., don't provide a blank {} implementation; just declare them. That way, you disable the default versions, and you get a compile error if any code ends up calling them. Whereas if you have a blank implementation, you could end up accidentally calling the copy constructor (more likely than the assignment operator) *from within the class code*, and wonder why you've got a bug (because obviously if it gets called from the class code by accident, then simply making it private won't help you. The only reason I can think of not to do this is if declaring without implementing causes problems on some compilers.
If one is refactoring a struct in existing code (as is the page premise), one does not need to worry about copy constructors, etc. The operations are already defined and implemented, the existing code is merely being moved into a common class. When refactoring, keep it simple and progress in small steps. Do not throw in code due to text book fears that it might be needed, only add things as they are needed with the appropriate tests to verify operation.
Compare with UseStructsNotClasses