I have been bitten by exactly the bug you describe to argue!
in reply to Re: Tutorial: Introduction to Object-Oriented Programming
in thread Tutorial: Introduction to Object-Oriented Programming
As mentioned elsewhere in the comments on your post, the only realy problem with your implementation of accessors is code maintenance - you need to add each get and set and then remember to add each store to the destroyer. I bet a lot of memory leaks would appear by forgetting to do this.
A comment by fruiture suggests a single data repository in the parent object with single get and set methods that take attribute names, but that implementation uses a hash internally and leaves you open to the same problem. It does, however, address both maintenance issues.
The same comment also points out that by avoiding a hash you lose the ability to use Data::Dumper to debug your objects easily.
You could use this repository idea, but have a hash in your object specifying the name and type of each of the attributes, and run a check on every get and set call. As a bonus, you could also use this hash to drive data validation by specifying a data type and/or validator sub - the set function could then optionally run a data validation of requested.