Programming Forums
User Name Password Register
 

RSS Feed
FORUM INDEX | TODAY'S POSTS | UNANSWERED THREADS | ADVANCED SEARCH

Reply
 
Thread Tools Display Modes
Old May 15th, 2007, 5:28 AM   #1
rwm
Professional Programmer
 
Join Date: Jan 2007
Location: Cape Town
Posts: 291
Rep Power: 2 rwm is on a distinguished road
OOP design question

Hey!

I have a question about designing an OOP system:

Say we have a base class Base, and we derive a class Derived from Base. In the copy constructor, of Derived, one would have to call the methods that operate on the Base classes data, i.e

class Base {
	public:
		Base() {
			a = 99;
			b = 101;
			c = 2232;
		}
		Base(const Base &src) {
			a = src.a;
			b = src.b;
			c = src.c;
		}
		~Base() {}
		int GetA() { return a; }
		void SetA(int _a) { a = _a; }
		int GetB() { return b; }
		void SetB(int _b) { b = _b; }
		int GetC() { return c; }
		void SetC(int _c) { c = _c; }
	private:
		int a;
		int b;
		int c;
};

class Derived : public Base {
	public:
		Derived() : Base() {
			data = 34334;
		}
		Derived(const Derived &src) {
			SetA(src.GetA());
			SetB(src.SetB());
			SetC(src.SetC());
			data = src.data;
		}
		~Derived() {}
		int GetData() { return data; }
		void SetData(int d) { data = d; }
	private:
		int data;
};

now my question is; is it ok to make the data of Base protected, so i can directly access them in the copy constructor? like this:

	Derived(const Derived &src) {
		a = src.a;
		b = src.b;
		c = src.c;
	}

i feel this is not a safe method? since any class taht derives from Base can access this data - when i want to keep it unaccessible...

is there an easier way to copy construct? or do I have to call Base's public methods to do this?

please help! thanks!
rwm is offline   Reply With Quote
Old May 15th, 2007, 9:25 AM   #2
Seif
Hobbyist Programmer
 
Seif's Avatar
 
Join Date: Jan 2006
Location: UK
Posts: 215
Rep Power: 3 Seif is on a distinguished road
well it kind of makes sense for derived classes to have access to ones base classes protected attributes. I would consider a review of what you have designed.

that said however, you could look into a friend class, it seems to be what you are looking for:

http://www.codersource.net/cpp_tutorial_friend.html

This will allow one class to have access to the private data of the class that declared it a friend.
Seif is offline   Reply With Quote
Old May 15th, 2007, 9:40 AM   #3
rwm
Professional Programmer
 
Join Date: Jan 2007
Location: Cape Town
Posts: 291
Rep Power: 2 rwm is on a distinguished road
Hey Seif!

Thanks for the reply! Mmm well I suppose its ok... Just wondered what some would have to say about hte issue...

It seems better to use protected members than to declare the class as a friend. It breaks the whole OOP structure... I guess?
rwm is offline   Reply With Quote
Old May 15th, 2007, 10:10 AM   #4
DaWei
Resident Grouch
 
DaWei's Avatar
 
Join Date: Jun 2005
Posts: 6,453
Rep Power: 10 DaWei is on a distinguished road
It really depends on what the classes are for and what you're actually trying to accomplish. Look at your getters and setters. They don't really protect your data. They allow the user to set any value that user wishes, but they only force him to do that in a roundabout way. That's obfuscation, not protection.

The purpose of a setter is to protect the data from being improperly set. You apparently have no rules to break, so there's nothing to protect. If, on the other hand, b should only be in the range 0-9, your setter can enforce that, whereas direct access cannot.

Once you've defined a useful setter, then you need a getter because you've shut the member down for direct access.

If you want to break that protection for any other class, then you have to know that unconstrained actions by that other class can't break your functionality. You're the designer. Only you know, unless you tell.

Relaxing that protection does not "break the OOP." Your object is still an object. It only breaks (possibly) the integrity of that object, functionally speaking.

Consider the accelerator on your car. It allows a specific range of inputs for fuel flow. Internal methods operate on that range to add a specific range of airflow to mix with it. That doesn't keep an unprotected member, say the butterfly valve, from being farbled with independently, thus modifying the intended behavor. Should you leave the butterfly valve out in the open, protect it somewhat with an aircleaner, or put the whole assembly in a welded-closed box? Your call.
__________________
Abstraction doesn't make it impossible to write bad code; it makes it possible to write superior code.
Contributor's Corner: Grumpy on C++ Exceptions DaWei on Pointers

Last edited by DaWei; May 15th, 2007 at 10:23 AM.
DaWei is offline   Reply With Quote
Old May 16th, 2007, 3:14 AM   #5
rwm
Professional Programmer
 
Join Date: Jan 2007
Location: Cape Town
Posts: 291
Rep Power: 2 rwm is on a distinguished road
Hey DaWei!

Thanks for the explanation - that was very helpful! Of course, it all makes sense, the user can never access private or protected data, only public, so, in my case, the classes that the client will operate on can access/modify the Base class data, but not directly, only through the public member functions passed on through the hierarchy. So obviously its ok to make the data protected for all the derived classes - since it makes copy constructing much easier...

Thanks again!
rwm is offline   Reply With Quote
Old May 26th, 2007, 2:59 PM   #6
Game_Ender
Professional Programmer
 
Game_Ender's Avatar
 
Join Date: May 2006
Location: Maryland, USA
Posts: 306
Rep Power: 3 Game_Ender is on a distinguished road
I am really surprised no one gave the OP the answer he was actually looking for the "right" way to copy construct a derived class is to call the copy constructor of the super class like so:
cpp Syntax (Toggle Plain Text)
  1. Derived(const Derived &src) :
  2. Base(src)
  3. {
  4. data = src.data;
  5. }
This allows you to keep all your data private as long you make the copy constructor public or protected.
__________________
Robotics @ Maryland AUV Team - Software Lead
Game_Ender is offline   Reply With Quote
Old May 26th, 2007, 6:48 PM   #7
grumpy
Programming Guru
 
grumpy's Avatar
 
Join Date: Jun 2005
Location: Adelaide, South Australia
Posts: 1,223
Rep Power: 5 grumpy is on a distinguished road
Close, Game_Ender.

A preferable way would often be;
// Base constructor within class Base
Base(const Base &src) : a(src.a), b(src.b), c(src.c)
{
}


//  Derived constructor within class Derived
Derived(const Derived &src) : Base(src), data(src.data)
{
}
This is preferable if one assumes that (1) the members of both classes are either basic types OR have their own copy constructors that work as expected. AND (2) it is necessary to hand-roll the copy constructor for both class Base and Derived.

One additional rule of thumb is also that, if a class needs a hand-rolled copy constructor, it also needs a hand-rolled assignment operator.

In practice, if assumption (1) is true, then assumption (2) is rarely true. In the particular example, it is not actually necessary to hand-roll a copy constructor for either class Base or class Derived: the compiler generated versions work fine.

int is a basic type. So I would actually implement the classes in rwm's first example as;
class Base {
	public:
		Base() {
			a = 99;
			b = 101;
			c = 2232;
		}

                // look Ma:  no hand-rolled copy constructor

		~Base() {}
		int GetA() { return a; }
		void SetA(int _a) { a = _a; }
		int GetB() { return b; }
		void SetB(int _b) { b = _b; }
		int GetC() { return c; }
		void SetC(int _c) { c = _c; }
	private:
		int a;
		int b;
		int c;
};

class Derived : public Base {
	public:
		Derived() : Base() {
			data = 34334;
		}

                // look Ma:  no hand-rolled copy constructor

		~Derived() {}
		int GetData() { return data; }
		void SetData(int d) { data = d; }
	private:
		int data;
};
grumpy is offline   Reply With Quote
Old May 28th, 2007, 2:46 AM   #8
rwm
Professional Programmer
 
Join Date: Jan 2007
Location: Cape Town
Posts: 291
Rep Power: 2 rwm is on a distinguished road
hey guys I already know how to copy construct - sometimes i just miss stuff hwne i type out - im at work - always on the rush! but thanks for the replies - was intersting read!
rwm is offline   Reply With Quote
Reply

Bookmarks

« Previous Thread in Forum | Next Thread in Forum »

Currently Active Users Viewing This Thread: 1 (0 members and 1 guests)
 
Thread Tools
Display Modes

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Forum Jump

Similar Threads
Thread Thread Starter Forum Replies Last Post
object design question rwm C++ 21 May 11th, 2007 7:11 AM
The Black Art of Video Game Console Design lostcauz Book Reviews 0 Apr 26th, 2006 7:31 PM
Attitudes Oddball Coder's Corner Lounge 29 Mar 18th, 2006 9:34 PM
How to post a question nnxion C++ 10 Jun 3rd, 2005 11:53 AM
How to post a question nnxion C 0 Jun 3rd, 2005 8:55 AM




DaniWeb IT Discussion Community
All times are GMT -5. The time now is 10:44 AM.

Powered by vBulletin® Version 3.7.0, Copyright ©2000 - 2008, Jelsoft Enterprises Ltd.
Copyright ©2007 DaniWeb® LLC