473,396 Members | 2,052 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,396 software developers and data experts.

A class that uses another class's objects

21
After reading some books in c++,I know that it is better to hide the data members ,but sometimes the rule makes everything messy and terrible ! For example
Expand|Select|Wrap|Line Numbers
  1. class Node{
  2. private:
  3.     int key;
  4.     Node *left;
  5.     Node *right;
  6. pubic:
  7.   // I have to provide a lot of method so that other class can deal with the node!!!
  8.     Node();
  9.     int getKey();
  10.     void setKey();
  11.     Node *getLeft();
  12.     Node *getRight();
  13.     //...
  14. };
  15. class Tree{
  16. private:
  17.    Node *root;
  18. public://...
  19. };
  20.  
The annoying thing here is that,in Tree's method,if I want to use the key of left of a Node *node, I must write: node->getLeft()->getKey() !!! Omg !!!

I also think of the alternative that just write the class Tree only, but if so, how can we use the root ?(Because we programming with new and delete,it is better to deal all with pointers,isn't it ?And if we declare
Expand|Select|Wrap|Line Numbers
  1. class Tree{
  2.   int key;
  3.   Tree* left;
  4.   Tree* right;
  5. //...
  6. };
  7.  
so in the methods,we can only use THIS to refer to the root . But this->...=... is not allowed ! That's another problem !
Please help me .
________________
Regards
Jul 19 '07 #1
17 2152
ravenspoint
111 100+
Oh boy! Here we go!

IMHO, despite what the textbooks say, I prefer to keep attributes public unless they are interdependant or potentially invalid. If there are combinations of attributes that are invalid, then this needs to be checked inside set methods, whose use is enforced by making the involved attributes private.

If all values, and all combinations, of attributes are valid, then save yourself a lot of typing by making them public.
Jul 19 '07 #2
seforo
60
You rather use structs and then define some functions to work on the members of struct other than declare data members of the class as public. If you declare data members of the class public, you are destroying the concept of data encapsulation.
Jul 19 '07 #3
ravenspoint
111 100+
seforo is correct - a class is just a fancy term for a struct, with a few extra bells and whistles. Sometimes, though, the bells and whistles are useful, so it is many years since I used a struct where a class works.

As for "destroying the concept of data encapsulation", well, as a practical coder, if such a terrible sin saves me some typing, then I will have to be a sinner.
Jul 19 '07 #4
weaknessforcats
9,208 Expert Mod 8TB
As for "destroying the concept of data encapsulation", well, as a practical coder, if such a terrible sin saves me some typing, then I will have to be a sinner.
It's not the saving of typing that's important. It's the hiding of the implementation.

By not hiding the implementation (like using public data members) you cause the users to encode your member names in their applications. Now it you need to redesign your class (or struct) the users will need to change their code. With a large user base, you will be prevented from making your change. Your product dies at this point.

It is essential to keep ripple at a minimum. If you don't do this, the object design cycle (analyze, design, code) is not possible. You need working objects that stay working through repeated redesign cycles with no impact on users.

Case in point: A Date class that has integers for month, day and year. The users have the data names for month, day and year in their code. Now the management decides to use a CIM date (yyyymmddhhmissnnnn). Unfortumately, installing this from of Date will require modification of user code. A small change has now become a big change.

However, the saving of typing is significant. It's lazy.
Jul 19 '07 #5
ravenspoint
111 100+
It's not the saving of typing that's important. It's the hiding of the implementation.

By not hiding the implementation (like using public data members) you cause the users to encode your member names in their applications. Now it you need to redesign your class (or struct) the users will need to change their code. With a large user base, you will be prevented from making your change. Your product dies at this point.

It is essential to keep ripple at a minimum. If you don't do this, the object design cycle (analyze, design, code) is not possible. You need working objects that stay working through repeated redesign cycles with no impact on users.

Case in point: A Date class that has integers for month, day and year. The users have the data names for month, day and year in their code. Now the management decides to use a CIM date (yyyymmddhhmissnnnn). Unfortumately, installing this from of Date will require modification of user code. A small change has now become a big change.

However, the saving of typing is significant. It's lazy.

weaknessforcats is correct, if you are creating libraries for other coders to use. Very few people, in reality, do this. If you are writing for yourself, and you change the design, then it is a simple matter to refactor, with the compiler pointing out where changes are needed.

Saving typing is not JUST lazy. It can also mean the difference between profit and loss on a coding contract, won against coders in low-wage economies all around the world. A successful coder needs to know how to produce reliable code, fast. He does not need to worry about hiding the implementation and breaking the concept of encapsulation.
Jul 19 '07 #6
ravenspoint
111 100+
Let me state my position more fully.

The 'private' keyword strikes me as nonsensical. It does not make the attribute private in any meaningful sense, all it does is enforce the use of accessor methods. If all your accessor methods look like this

Expand|Select|Wrap|Line Numbers
  1. setAttribute1( int i ) { myAttribute1 = i; }
  2. int getAttribute( ) { return myAttribute1; }
  3.  
then you are wasting your time - the compiler is going to optimize away your typing anyway.

Now, weaknessforcats is correct: if you are providing a library for other's to use in their code, it is important to hide your implementation from them. Unfortunately, private does no such thing. You will still receive endless grief when some yahoo edits, and breaks, your code then reports a bug.

This, among other conveniences, is why you use COM to expose your methods.
Jul 19 '07 #7
weaknessforcats
9,208 Expert Mod 8TB
Saving typing is not JUST lazy. It can also mean the difference between profit and loss on a coding contract, won against coders in low-wage economies all around the world. A successful coder needs to know how to produce reliable code, fast. He does not need to worry about hiding the implementation and breaking the concept of encapsulation.
This is great. I actually made a good living doing things just this way. At the time (1965-1990) my phrase for it was: Gee, the guy that coded this thing must have been a chimpanzee. But do not fear. Let me rewrite you application correctly, and all of your bugs will go away.

Then I rewrote the application using my own style causing the next guy to throw it away and start over.

Throw-away code os OK for applications you can hold in your head or have limited distribution (like the computer is in the basement and the users on on the second floor). But in any real, modern, application, you cannot afford to recode every time. Even if the thing is slower, reuse trumps recode every time.

You code for reuse.

The 'private' keyword strikes me as nonsensical. It does not make the attribute private in any meaningful sense, all it does is enforce the use of accessor methods. If all your accessor methods look like this
That is not the point of private inheritance. Private inheritance (also called implementation inheritance) occurs when you want the implementation of the class but do not want the class interface. Accessor functions are not mandated. It's almost the same as HAS-A where the class is represented by a private object.

This, among other conveniences, is why you use COM to expose your methods.
COM fails to separate the interface from the implementation. COM was developed intiailly in C and ported to C++ when it was still fashionable to use public virtual functions. Check out the design pattern called Template Method so see how (and why) you separate your interface from your implementation.

Also, COM does not work in Unix or Linux.
Jul 19 '07 #8
ravenspoint
111 100+
"That is not the point of private inheritance."

I do not believe we were talking about private inheritance. We were talking about private attributes.

I know very little about private inheritance. I find that I rarely use inheritance in real work. It looks great in textbooks, I suppose, but is hardly ever necessary to solve a problem.

As for re-use, well copy and paste does the job for me :-)
Jul 19 '07 #9
weaknessforcats
9,208 Expert Mod 8TB
I do not believe we were talking about private inheritance. We were talking about private attributes.
I'm guessing you don't hard-code numbers in your programs. I'm guessing you use macros instead.

#define MAX 10

and have 10,000 occurances of MAX rather than 10,000 hard-coded 10's.

A public arttribute is the same as hard-coding a 10.

You want a function MyClass::MAX() that returns the current max value. The current max value is private. The MyClass::MAX() is public.
Jul 19 '07 #10
ravenspoint
111 100+
I'm guessing you don't hard-code numbers in your programs. I'm guessing you use macros instead.

#define MAX 10

and have 10,000 occurances of MAX rather than 10,000 hard-coded 10's.

A public arttribute is the same as hard-coding a 10.

You want a function MyClass::MAX() that returns the current max value. The current max value is private. The MyClass::MAX() is public.
I disagree.

Using the define helps to disambiguate ( is that 10 the base of the number system or the maximum array dimension or some other 10 used for some other reason? A search is going to overwhelm with many different uses of 10, MAX will, hopefully, be used for just one thing.)

MyClass::MAX() as opposed theclass.max does not have this advantage and is a pain for something that will be optimized away.
Jul 19 '07 #11
weaknessforcats
9,208 Expert Mod 8TB
MyClass::MAX() as opposed theclass.max does not have this advantage and is a pain for something that will be optimized away.
There are asumptions here:
1) that max is a class member
2) that MyClass::MAX() will be optrimized away. It may have to get the current max from a registry somewhere rather than some simple return.
3) that the future can be foretold. That is, if max is a public class member, and is used in 10,000 places, that you will never need to get the current max value from a registry. If you have to, you will need to make 10,000 changes instead of changing MyClass::MAX(), recompiling one file and re-linking.
Jul 19 '07 #12
ravenspoint
111 100+
There are asumptions here:
1) that max is a class member
2) that MyClass::MAX() will be optrimized away. It may have to get the current max from a registry somewhere rather than some simple return.
3) that the future can be foretold. That is, if max is a public class member, and is used in 10,000 places, that you will never need to get the current max value from a registry. If you have to, you will need to make 10,000 changes instead of changing MyClass::MAX(), recompiling one file and re-linking.
1) I have already explicitly made this assumption. Read earliest posts

2) ditto

3) global search and replace is your friend.

Me, I think that you are making a very strange assumption. You are prepared to do a lot of work now, every day, just on the off-chance that a low probability event might cause extra work some day in the future. Perhaps you are paid by the hour?
Jul 19 '07 #13
JosAH
11,448 Expert 8TB
might [/b]cause extra work some day in the future. Perhaps you are paid by the hour?
I'm with WeaknessForCats here: there's a huge difference between scientific
and/or industrial strength software and home brew one-man cleverness. The off-
chance occasions are not so rare according to Murphy and low probability
events show up sooner than you want them. You obviously have never been
there which doesn't matter but please don't blame me when you hit it.

kind regards,

Jos
Jul 19 '07 #14
Banfa
9,065 Expert Mod 8TB
3) global search and replace is your friend.
Actually "only having to change the code in 1 place" is your friend, a global search and replace is asking for trouble and time spent debugging and fixing compiler errors.

In fact I would have thought that it is self-evident that the more code changes you perform the more likely you are to introduce a bug to the code.

I too am with WeaknessforCats on this. The class should expose an interface and keep it's data hidden it is more defensive, and you maintain a better control of what is going on.

Your argument of time wasted typing extra characters is a particularly poor one, in my experience the time spent typing is far outweighed by the time spent thinking, designing, testing and maintaining.

Data encapsulation makes both testing and maintaining easier and quicker.
Jul 19 '07 #15
VanKha
21
Can weaknessforcast explain the case more clearly(sorry,I don't understand)
For example
//not really coding
int max;
int MAX();//max is public and we use a function to get it
or
private:
int max;
public:
int MAX();// max is private and we use an accesor method
if we use max 1000 times in a program,it would be disaster when there's a change(such as taking max from registry,as you mentioned).That's right.But the two above solutions can be modified for reuse reason : we only have to change the code of function(in both case)!!!
In brief,my opinion is that why you compare using private with using directly data, but you not mention that using private also takes the same amount of time to change the code with using public ? In other words,what makes private strategy more interesting ?
Jul 20 '07 #16
JosAH
11,448 Expert 8TB
Can weaknessforcast explain the case more clearly(sorry,I don't understand)
For example
//not really coding
int max;
int MAX();//max is public and we use a function to get it
or
private:
int max;
public:
int MAX();// max is private and we use an accesor method
if we use max 1000 times in a program,it would be disaster when there's a change(such as taking max from registry,as you mentioned).That's right.But the two above solutions can be modified for reuse reason : we only have to change the code of function(in both case)!!!
In brief,my opinion is that why you compare using private with using directly data, but you not mention that using private also takes the same amount of time to change the code with using public ? In other words,what makes private strategy more interesting ?
Encapsulation. Here's an extremely simple and artificial example: suppose you
have a temperature registering device: it registers temperartures in degrees
Fahrenheit and it's very accurate so you define a public member:

Expand|Select|Wrap|Line Numbers
  1. public:
  2. double fahrenheit;
  3.  
You base all your super-duper clever calculations on this public member. Until
one sad day that temperature registering device manufacturer is out of business.
The only alternative is another (European) company that produces those
temperature registering devices but they register temperatures in Celcius because
they're metric.

How you'd wish you had done this instead in the old days:

Expand|Select|Wrap|Line Numbers
  1. private:
  2. double fahrenheit;
  3. public:
  4. double getFahrenheit() { return fahrenheit; }
  5.  
and based all your super-duper clever calculations on that public method instead.
All you had to do in the new situation would be this:

Expand|Select|Wrap|Line Numbers
  1. private:
  2. double celcius;
  3. public:
  4. double getFahrenheit() { return 9.0/5.0*(celcius+32); }
  5.  
But since you didn't, you have to modify all your dependent code. Suppose you
had an installed user base: you'd be out of business as well then.

kind regards,

Jos
Jul 20 '07 #17
After reading some books in c++,I know that it is better to hide the data members ,but sometimes the rule makes everything messy and terrible ! For example
Expand|Select|Wrap|Line Numbers
  1. class Node{
  2. private:
  3.     int key;
  4.     Node *left;
  5.     Node *right;
  6. pubic:
  7.   // I have to provide a lot of method so that other class can deal with the node!!!
  8.     Node();
  9.     int getKey();
  10.     void setKey();
  11.     Node *getLeft();
  12.     Node *getRight();
  13.     //...
  14. };
  15. class Tree{
  16. private:
  17.    Node *root;
  18. public://...
  19. };
  20.  
The annoying thing here is that,in Tree's method,if I want to use the key of left of a Node *node, I must write: node->getLeft()->getKey() !!! Omg !!!

I also think of the alternative that just write the class Tree only, but if so, how can we use the root ?(Because we programming with new and delete,it is better to deal all with pointers,isn't it ?And if we declare
Expand|Select|Wrap|Line Numbers
  1. class Tree{
  2.   int key;
  3.   Tree* left;
  4.   Tree* right;
  5. //...
  6. };
  7.  
so in the methods,we can only use THIS to refer to the root . But this->...=... is not allowed ! That's another problem !
Please help me .
________________
Regards
You can use the friend keyword and create a special relationship between Node and Tree class as follows;

class Node
{
...
friend class Tree;
}

Now the member functions of class Tree for e.g. Tree::DumpTree(Node* n) can use
{
...
if (n == null)
return;
printf("%s", n->name);
DumpTree(n->left);
DumpTree(n->right);
...
}

friend(ship) is useful when the relationship between objects are strong like in this case where a tree is basically a node itself (inheritance) and has node objects (composition).
Sep 15 '07 #18

Sign in to post your reply or Sign up for a free account.

Similar topics

2
by: Krzysztof Stachlewski | last post by:
I tried to run the following piece of code: Python 2.3.4 (#53, May 25 2004, 21:17:02) on win32 Type "help", "copyright", "credits" or "license" for more information. >>> o = object() >>> o.a...
9
by: justanotherguy63 | last post by:
Hi, I am designing an application where to preserve the hierachy and for code substitability, I need to pass an array of derived class object in place of an array of base class object. Since I...
12
by: Manolis | last post by:
Hi, I was wondering if there is any way to make two objects of the same class to be able to access each other's private data, like this: class A { public: void access( const A& a )...
10
by: Brett | last post by:
I'm still trying to figure out concrete reasons to use one over the other. I understand the abstract class can have implementation in its methods and derived classes can only inherit one abstract...
7
by: krs | last post by:
Hi, I'm using the MS timetracker app as a basis for an application I am building. I have at present two classes, Site and SitesCollection, similar to the timeentry and timeentrycollection...
7
by: jsale | last post by:
I have made an ASP.NET web application that connects to SQL Server, reading and writing data using classes. I was recommended to use session objects to store the data per user, because each user...
16
by: A_PK | last post by:
Hi, I am a VB.net beginner, I do not know what are the major difference between Module vs Class. Could someone guide me when is the best situation to use Module or Class. I have no idea...
2
by: Fish | last post by:
I have been researching the correct way to organize my solution so that it makes best use of VB.NET inherent ability to manage resources such as objects. My solution contains 2 projects and the...
36
by: Cap'n Ahab | last post by:
I have used VB3 - VB6, so learning all this OO stuff is reasonably new to me (although I looked at Java a few years ago). Anyway, I thought I would write a small class to begin with, with a...
4
by: Mark | last post by:
I want to create a collection class that will be strongly typed (store a specific object type), be keyed with a case insensitive string, and be able to access objects stored by index, or...
0
by: Charles Arthur | last post by:
How do i turn on java script on a villaon, callus and itel keypad mobile phone
0
by: emmanuelkatto | last post by:
Hi All, I am Emmanuel katto from Uganda. I want to ask what challenges you've faced while migrating a website to cloud. Please let me know. Thanks! Emmanuel
1
by: nemocccc | last post by:
hello, everyone, I want to develop a software for my android phone for daily needs, any suggestions?
1
by: Sonnysonu | last post by:
This is the data of csv file 1 2 3 1 2 3 1 2 3 1 2 3 2 3 2 3 3 the lengths should be different i have to store the data by column-wise with in the specific length. suppose the i have to...
0
by: Hystou | last post by:
There are some requirements for setting up RAID: 1. The motherboard and BIOS support RAID configuration. 2. The motherboard has 2 or more available SATA protocol SSD/HDD slots (including MSATA, M.2...
0
Oralloy
by: Oralloy | last post by:
Hello folks, I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>". The problem is that using the GNU compilers,...
0
jinu1996
by: jinu1996 | last post by:
In today's digital age, having a compelling online presence is paramount for businesses aiming to thrive in a competitive landscape. At the heart of this digital strategy lies an intricately woven...
0
tracyyun
by: tracyyun | last post by:
Dear forum friends, With the development of smart home technology, a variety of wireless communication protocols have appeared on the market, such as Zigbee, Z-Wave, Wi-Fi, Bluetooth, etc. Each...
0
agi2029
by: agi2029 | last post by:
Let's talk about the concept of autonomous AI software engineers and no-code agents. These AIs are designed to manage the entire lifecycle of a software development project—planning, coding, testing,...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.