Help in my program using Classes

  • Thread starter yungman
  • Start date
  • #51
5,066
120
As has been mentioned before, this is NOT the way your 'Directory' program should be broken down.

Classes should NOT be used to collect fuctions according to what they do, they should be used to collect functions together with the entity they do it to.

Your directory class should have the following public methods:
Code:
Directory::readFile;
Directory::writeFile;
Directory::add;
Directory::find;
Directory::sort;
Thanks for the reply.

I thought it's more logical to have a class to write and read file with a given vector of structure. Then one class to handle the vector manipulations.

In my mind, ultimately, I want the vectorManage class to receive any vector with a specific member variable used for sorting( second for finer sorting like first name) but NOT specific to last name or first name. Then another class to read write file with a vector and name/destination of the file as parameters. This way, it will be general purpose for other use. for example if I want to do an inventory program with parts given the part number. I can use the same two classes, I can sort the parts and save in file.

With that, I can make the two classes as general purpose. Directory is only one of the program that uses this two classes.

What you suggested is more like a member function within the vectorManage. Isn't better to put those in the Implementation files .cpp?

Thanks
 
Last edited:
  • #52
34,265
5,903
Repeating @pbuk's post:
Your directory class should have the following public methods:
Code:
Directory::readFile;
Directory::writeFile;
Directory::add;
Directory::find;
Directory::sort;
I thought it's more logical to have a class to write and read file with a given vector of structure. Then one class to handle the vector manipulations.
Several of us, including pbuk and myself, disagree with your logic here.
With that, I can make the two classes as general purpose. Directory is only one of the program that uses this two classes.
Directory is not a program -- it is the main class in your program. Many of us maintain that it should be the only class.
What you suggested is more like a member function within the vectorManage.
No, not at all. pbuk was very specific in what he wrote. All five functions are members of the Directory class.
Isn't better to put those in the Implementation files .cpp?
I think you might be confused here. The header file for Directory would give the class definition, together with declarations (only) for the member functions. The .cpp file would provide the definitions (the bodies) of those member functions.
 
Last edited:
  • Like
Likes sysprog and Vanadium 50
  • #53
5,066
120
Repeating @pbuk's post:
Several of us, including pbuk and myself, disagree with your logic here.
Directory is not a program -- it is the main class in your program. Many of us maintain that it should be the only class.
No, not at all. pbuk was very specific in what he wrote. All five functions are members of the Directory class.
I think you might be confused here. The header file for Directory would give the class definition, together with declarations (only) for the member functions. The .cpp file would provide the definitions (the bodies) of those member functions.
I thought class should be a template to perform certain function, not just splitting up the program to smaller pieces.

I know you all said I am taking too big of a bite, But this is a goal that I want to pursue. I look at a class should be more general purpose that other programs can use. Like I envision a class of vector management that take argument of any structure to store in a vector. The structure has a member say called mainSort(Used as last name in my program) that the vector class know to use it to sort the order. Then another member of the structure called say fineSort(used as firstname) to refine sorting. The vectorManage class also perform adding, deleting. Then another general purpose fileManage class to take in the pointer to a vector and the name/location of the file as two arguments to read and write files of different names and into different locations.

I thought this is the goal of having classes that different programs can use. I can envision Inventory program can use this, using part number ( in character) for sorting, you then can have cost, description and others which vectorManage class doesn't even care as long as it knows to sort the order. Then a general purpose fileManage class to just blindly read and write to file according to argument of the pointer to the vector AND the file name and location.

I envision I can do Employee information and some other programs that need to use these two classes.

I know, this is again a big step, but hey, one can dream. Using friends is ONLY the first step that I know to make the program to have two header files, that is more important than anything else at this point for me. Doing the program in my ultimate goal is still quite far off. But one step at a time.
 
  • #54
34,265
5,903
I thought class should be a template to perform certain function
No. A class should represent some thing. The class should contain all the methods that are needed by whatever the thing is -- methods for creating and destroying the thing, updating the thing, and so on.
I look at a class should be more general purpose that other programs can use. Like I envision a class of vector management that take argument of any structure to store in a vector.
You're not thinking in terms of object oriented programming. Instead, what you're doing is procedural programming with a thin veneer of classes.
I thought this is the goal of having classes that different programs can use.
Right, it is. But a class should represent some thing, like a Person or a Directory or a Widget. You are not doing object-oriented programming (OOP) if you have one class for, say, entering a person, and another for saving that person's data to disk.
Using friends is ONLY the first step that I know to make the program to have two header files, that is more important than anything else at this point for me.
Why is it important to have two header files? You're letting this goal get in the way of understanding good object-oriented programming design.
 
Last edited:
  • Like
Likes Vanadium 50, sysprog, yungman and 1 other person
  • #55
pbuk
Science Advisor
Gold Member
1,735
628
I look at a class should be more general purpose that other programs can use.
That is called a library, like the Standard Template Library (STL). The classes you (and I, and 99% of all programmers) write are not libraries, they use libraries that other people have written to implement functionality specific to the entity.

Like I envision a class of vector management that take argument of any structure to store in a vector.
That is what std::vector is.

The structure has a member say called mainSort(Used as last name in my program) that the vector class know to use it to sort the order. Then another member of the structure called say fineSort(used as firstname) to refine sorting.
std::sort exists to sort vectors.

The vectorManage class also perform adding, deleting.
std::vector is not very well suited to deleting elements; you would be better off with std::list or std::map.

STOP trying to guess for yourself what Object Oriented Programming means and learn it properly. If you are not picking this up from the book you are using, ask for some more examples. Here are some: https://www3.ntu.edu.sg/home/ehchua/programming/cpp/cp3_OOP.html.
 
  • Like
Likes sysprog, Vanadium 50, yungman and 1 other person
  • #56
5,066
120
Ah!! So class is NOT like library or Template type of general purpose. I thought that's what class is for!!

But then I fail to see what's class for, other than just separate function into separate files instead writing all the functions in one big program.

So what I did is ok, I just stuff all the little file in .cpp and get over with it.

I can't wait to study library and Template.
 
  • #57
pbuk
Science Advisor
Gold Member
1,735
628
But then I fail to see what's class for,
In your application it would make sense to have a class called Directory for doing every thing you want to do with a Directory (load from disk, add an Entry, sort etc.). It might also make sense to have a class called Entry for doing everything you want to do with a directory entry (add an email address, change the name to correct a typo etc.), replacing the struct you are currently using for directory entries. I have seen classes in C++ introduced as 'structs on steroids', although like all analogies you can take this too far.

other than just separate function into separate files instead writing all the functions in one big program.
In a way that is exactly what we are doing - although because we are not just separating functions but also variables, constants etc. we say we are separating concerns into different files. 'Separation of concerns' is an important goal in programming; it means when something is broken you know where to start looking to fix it.

In your program you might have 4 files:
FileConcern
main.cppReading from the command line and dispatching corresponding actions
directory.hSpecifying the interface for the Directory class
directory.cppImplementing everything concerned with Directories
entry.hSpecifying the interface for the Entry class
entry.cppImplementing everything concerned with Entries
 
  • Like
Likes sysprog and yungman
  • #58
5,066
120
In your application it would make sense to have a class called Directory for doing every thing you want to do with a Directory (load from disk, add an Entry, sort etc.). It might also make sense to have a class called Entry for doing everything you want to do with a directory entry (add an email address, change the name to correct a typo etc.), replacing the struct you are currently using for directory entries. I have seen classes in C++ introduced as 'structs on steroids', although like all analogies you can take this too far.


In a way that is exactly what we are doing - although because we are not just separating functions but also variables, constants etc. we say we are separating concerns into different files. 'Separation of concerns' is an important goal in programming; it means when something is broken you know where to start looking to fix it.

In your program you might have 4 files:
FileConcern
main.cppReading from the command line and dispatching corresponding actions
directory.hSpecifying the interface for the Directory class
directory.cppImplementing everything concerned with Directories
entry.hSpecifying the interface for the Entry class
entry.cppImplementing everything concerned with Entries
Ha ha, this is so anti climatic!!! I was so excited and wrote this big program thinking I am a step ahead. If I knew all these, I might not even write the program. It's just external function with a twist. I think I am going to take a day off today. I was so excited about this thinking I can make a general purpose function to be called and I think so hard about this. What a let down. But thanks for telling me about this, it's better knowing this now than to waste another two weeks doing more stupid things.

One thing though, I think I learn this part of class pretty good because of all these. I spent the whole day yesterday stepping through the programs with friends step by step to make sure I understand and nothing left behind!!! Now I just want to get to the overload part and looking forward to library and template stuffs before I get back to the program again.

Thanks
 
  • #59
5,066
120
Question: Is class most useful in splitting up a big program in logical way so more people can work on the program at the same time with the given spec and arguments passing. A good way to logically splitting up a big program?

Like the main program create the vector of structure, then call
1) A class of user interface to get the information and return to main().
2) main() call a sorting class to add the new info by passing the vector by reference to have the sorting class to add, sort and the vector.
3) main() call class for delete a name by passing vector by reference and name to delete and the class modify the vector.
4) When quiting the program, main() call the file class to write the vector to file.

This way, you can have different person writing one of the class without knowing each other, all they need is the reference to the vector and what to change etc.

Am I getting this correct? If this is so, I have a much better idea how to split the program. Main thing is to make sure each class don't interact with each other, everything control by main(). Without classes interact with each other, I don't need friends and all that, just a lot of different classes.

thanks
 
Last edited:
  • #60
34,265
5,903
Question: Is class most useful in splitting up a big program in logical way so more people can work on the program at the same time with the given spec and arguments passing. A good way to logically splitting up a big program?
No.
You can have a single class with the class methods implemented in multiple files. The class method implementations don't have to reside in just a single file. It's exactly the same in C or in non-OO C++ programs -- you could have main() in one file, and multiple other files in the project that each contain one function. Multiple people could work on the separate parts individually.
Like the main program create the vector of structure, then call
1) A class of user interface to get the information and return to main().
2) main() call a sorting class to add the new info by passing the vector by reference to have the sorting class to add, sort and the vector.
3) main() call class for delete a name by passing vector by reference and name to delete and the class modify the vector.
4) When quiting the program, main() call the file class to write the vector to file.
You're really missing the point of object-oriented programming, where the key idea is the object. What you describe above could just as well be done in any procedural language, like Fortran or Pascal or even C.
It really makes no sense at all to partition the program in the way you describe, with separate classes for getting the information, sorting the directory, deleting a name, storing the information to disk. Again the focus should be on the things that you're working with - the Directory and the entries that represent the individuals whose information will be in the directory.

The focus should not be the operations you want to perform on the objects.

There's a saying:
If the only tool you have is a hammer, everything looks like a nail.
You've learned a little bit about classes, and now you think everything should be a class. As was recommended earlier, it would be a good idea to back off for a bit, and learn something about how to design an object-oriented program.

@pbuk has given you some good advice that you seem to be ignoring.
pbuk said:
In your application it would make sense to have a class called Directory for doing every thing you want to do with a Directory (load from disk, add an Entry, sort etc.). It might also make sense to have a class called Entry for doing everything you want to do with a directory entry (add an email address, change the name to correct a typo etc.), replacing the struct you are currently using for directory entries.
Am I getting this correct?
Not at all.
 
Last edited:
  • Like
Likes pbuk and sysprog
  • #61
5,066
120
Well, I guess I give up, I just don't see what class is for anymore. I just get my program done the best way I know how and learn along the way. I can see the usefulness of structure as template, I totally don't see the point of class other than split one big file into many smaller files that can be done separately, helping to make the flow cleanly so signal( variables ) are not intertwine together. Way to make a clean divide the task for each module. AND of cause be able to split the task up so other people can work in parallel. That is about to most important thing in real life working environment. If not for that, I am not interested in the academic definition what the class supposed to do. Programming regardless of OOP or procedural, or any languages, are only tools, it's a means to an end, not the end of the means.

I might not experienced in programming, BUT believe me, I design and in charge a lot of big systems from top down for a really long time with success, how to divide project to different people, how to divide according to the function and clean interface. How to make it so I can change one module and not affecting the others as much as possible. This is from real life experience AND interfaced with a lot of software people. This is the way I would do if I write a program. AND I TRUST my experience.
 
Last edited:
  • #62
Vanadium 50
Staff Emeritus
Science Advisor
Education Advisor
2019 Award
25,633
8,816
The point of OOP is to make it easier for programmers and teams of programmers. It is intended to be more modular, to strengthen the distinction between implementation and interface, to allow more code reuse and reduce code duplication.

If you don't see the value, it is likely a combination of being new to this, and not following the advice of people like @pbuk and @Mark44 who have more experience - probably many thousand times as many lines of code.
 
  • #63
34,265
5,903
Well, I guess I give up, I just don't see what class is for anymore.
The book that you're using (Gaddis) tells you this. In my copy, the first edition, Gaddis describes the difference between procedural programming and object-oriented programming. C++ (and other OO languages provide support for OOP via the class construct.
In procedural programming, the programmer constructs procedures (or functions, as they are called in C++). The procedures are collections of programming statements that perform a specific task. The procedures each contain their own variables and commonly share variables with other procedures.
Object-oriented programming (OOP), on the other hand, is centered around the object. An object is a programming element that contains data and procedures that operate on the data. It is a self-contained unit. The objects contain, within themselves, both information and the ability to manipulate the information.
I'm reasonably certain that the edition you're using, 5th or 6th?, contains the same or similar information, probably in the very first chapter.


I can see the usefulness of structure as template,
In C++, there is essentially no difference between a struct and a class, other than the default access specifier for a struct is public, and the default access specifier for a class is private. Otherwise, there is no difference.
 
  • #64
5,066
120
No.
You can have a single class with the class methods implemented in multiple files. The class method implementations don't have to reside in just a single file. It's exactly the same in C or in non-OO C++ programs -- you could have main() in one file, and multiple other files in the project that each contain one function. Multiple people could work on the separate parts individually.
You're really missing the point of object-oriented programming, where the key idea is the object. What you describe above could just as well be done in any procedural language, like Fortran or Pascal or even C.
It really makes no sense at all to partition the program in the way you describe, with separate classes for getting the information, sorting the directory, deleting a name, storing the information to disk. Again the focus should be on the things that you're working with - the Directory and the entries that represent the individuals whose information will be in the directory.

The focus should not be the operations you want to perform on the objects.

There's a saying:

You've learned a little bit about classes, and now you think everything should be a class. As was recommended earlier, it would be a good idea to back off for a bit, and learn something about how to design an object-oriented program.

@pbuk has given you some good advice that you seem to be ignoring.


Not at all.
Actually, that's very similar to what my Directory program ALREADY in post#46. If you look back to my last program. I have one Specification file to handle both file and vector management. Then I have two separate .cpp files one for all the file read write, one for all the vector sorting. Having individual .cpp for each task is just a more expanded version. BUT, to me it's not clean, that's why I want to modulized even more, at least separate the file I/O from vector.

I get what you say about the class, the book said what you say. The book even said class is the "blue print" of a house and you can build a lot of house with the same blueprint. BUT, in real life, do you really have that many program that have to keep repeating the same "blueprint" over and over within the program? Like in my Directory, I only sort it one time when I add a new name!! I don't need "blueprint". It just creating more restrictions in the name of "making lives easier".

What is really really important in real live is being able to logically splitting the big program into smaller individual pieces by having clean parameters interface so people can work in parallel on the program AND more importantly, making it cleaner on signal(variables) flow for easier to troubleshoot.

I only study to chapter 14, there might be other better ways to split the program other than using classes. Just like I did not realize what I want that is very important to make it general purpose is covered in library and template instead of class. But if there is something exist to do the splitting, then the usefulness of class is very limited, nothing more than struct but with a lot more inconvenience.
 
  • #65
34,265
5,903
Actually, that's very similar to what my Directory program ALREADY in post#46.
Well, you split up the file management functions into multiple files, which is fine, but you still have two classes in your program
BUT, in real life, do you really have that many program that have to keep repeating the same "blueprint" over and over within the program? Like in my Directory, I only sort it one time when I add a new name!! I don't need "blueprint". It just creating more restrictions in the name of "making lives easier".
I don't think you understand how the blueprint business works in real world programs (i.e., programs with hundreds of thousands (or more) lines of code, being worked on by large teams of programmers.
A well designed Employee class could be used by programs used by HR, Payroll, Management, or other entities. Each different application would not need to "roll their own" to deal with an employee.
What is really really important in real live is being able to logically splitting the big program into smaller individual pieces by having clean parameters interface so people can work in parallel on the program AND more importantly, making it cleaner on signal(variables) flow for easier to troubleshoot.
If you design a program that is procedural, you get the problem you're describing, where one function has to be extra careful about what its parameters are. As a case in point, in which your interface was not clean and easy to troubleshoot, Jarvis said this (post #22):
I'm just glancing now. Is the vecC in main the same one in your file object
In main shouldn't you use file.vecC ?
Here was your reply:
I edit this post. I declared std::vector<Directory>DirV; in line 17 of vectorEdit.h, this should make DirV[] global. I should be able to use vectC.DirV in main() and fileManage.h.
Which is not a good solution. With object-oriented programming, done correctly, you don't run into problems like this.
A Directory class would have all the methods it needs to create or delete a directory, add an entry to a directory or remove one from it, save its contents to disk.
 
  • #66
5,066
120
................................
Here was your reply:
Which is not a good solution. With object-oriented programming, done correctly, you don't run into problems like this.
A Directory class would have all the methods it needs to create or delete a directory, add an entry to a directory or remove one from it, save its contents to disk.
You reading the right post#46? That's the final program, there is no fileManage.h in my program. That's how you described how it should be done. You are looking at the old program that I tried to have two Specification files. In my last program in post #46, I only have one fileVector.h header file. You can call it Directory or fileVector, it does exactly the thing you talked about.

What I want ultimately is to have two header files, one for only vector management with all the sort, add, delete in it. The other is file management that only read and write to file. They can have all the member function in separate Implementation files ( it absolutely does NOT make sense in the book to have Implementation with only one or two line function like int getCrap(){return crap;}) Why pull it out to the .cpp file for routine that is one liner?!!! AND there will be no interface between the two header files, no friends at all. Clean.
 
  • #67
pbuk
Science Advisor
Gold Member
1,735
628
Clean.
Clean? CLEAN???
  1. It is not clean to hard code the same filename in 6 different places.
  2. It is not clean to use cryptic method names like caseA.
  3. It is not clean to lay your code out randomly:
    1. sometimes placing a { in the same column as the previous statement, sometimes with 1, 2 or 4 additional spaces of indentation
    2. sometimes placing the next statement on the next line, sometimes on the same line as the { after 0, 1, 2 or 3 spaces
    3. etc. etc.
  4. It is not clean to write a comment "Assume file is OPEN already" and 2 lines later open the file.
  5. It is not clean to mix PascalCase and camelCase randomly for variable names.
  6. It is not clean to mix snake_case and camelCase randomly for method names (are you trying to achieve a record with sort_firstName?)
  7. It is not clean to use PascalCase for variable names and camelCase for class names (it IS clean to do this the other way round).
  8. It is not clean to write tolower('q').
  9. It is not clean to try to open the same file twice, do you think the computer tries harder to find it the second time?
  10. etc. etc.
 
  • Like
Likes phinds and Vanadium 50
  • #68
5,066
120
Clean? CLEAN???
  1. It is not clean to hard code the same filename in 6 different places. It's not wrong.
  2. It is not clean to use cryptic method names like caseA.Correspond to case 'a' which is what the user type in for "adding", r for replacing, d for deleting etc.
  3. It is not clean to lay your code out randomly:
    1. sometimes placing a { in the same column as the previous statement, sometimes with 1, 2 or 4 additional spaces of indentation
    2. sometimes placing the next statement on the next line, sometimes on the same line as the { after 0, 1, 2 or 3 spaces
    3. etc. etc.//Better than no indent. I don't want to start another line and make it harder to read. I hate seeing comment line between lines of codes, That is more disrupting.
  4. It is not clean to write a comment "Assume file is OPEN already" and 2 lines later open the file.//must be a mistake left over when I change the code.
  5. It is not clean to mix PascalCase and camelCase randomly for variable names.
  6. It is not clean to mix snake_case and camelCase randomly for method names (are you trying to achieve a record with sort_firstName?)
  7. It is not clean to use PascalCase for variable names and camelCase for class names (it IS clean to do this the other way round).
  8. It is not clean to write tolower('q').//This is how the book use.
  9. It is not clean to try to open the same file twice, do you think the computer tries harder to find it the second time?//Yes, with the inconsistency of all the computers and hardware. Don't even get me started on this.
  10. etc. etc.
Clean, I mean I am trying to make the program flow cleanly like I described in post#61. I am not good in coding and I made a lot of mistake. I am trying, I never say I am good right now, it's a goal I want to achieve.

To me, name is secondary to the design of the system. At this point where I am the only one that work on the program, I rather have shorter names so I don't have to use more lines. This is VERY IMPORTANT as when I print it out, I try to put the code in a single page, that make it a whole lot easier to read. This is IMPORTANT TO ME.

I have no idea what you are talking about pascal and camel.
 
  • #69
34,265
5,903
You reading the right post#46?
My comment had nothing to do with post #46. It referred to a comment by Jarvis in post 22, which I mentioned.
Mark44 said:
As a case in point, in which your interface was not clean and easy to troubleshoot, Jarvis said this (post #22):
Right after that, I quoted your post #23.
The comment had to do with why your earlier version was more complicated and difficult to troubleshoot (you had to get help from us here). I was attempting to convince you that an object-oriented design might be easier to work with.

yungman said:
To me, name is secondary to the design of the system. At this point where I am the only one that work on the program, I rather have shorter names so I don't have to use more lines.
If you truly were the only one working on the program, that might make some sense. But that isn't the case, as all of us here who have been reading your code, and trying to make some sense of what you are trying to do.
Choosing self-explanatory names for variables, functions, and classes should not be secondary to the design of a program. Making the code fit in fewer lines -- that should be secondary.
 
  • #70
5,066
120
My comment had nothing to do with post #46. It referred to a comment by Jarvis in post 22, which I mentioned.

Right after that, I quoted your post #23.
The comment had to do with why your earlier version was more complicated and difficult to troubleshoot (you had to get help from us here). I was attempting to convince you that an object-oriented design might be easier to work with.

If you truly were the only one working on the program, that might make some sense. But that isn't the case, as all of us here who have been reading your code, and trying to make some sense of what you are trying to do.
Choosing self-explanatory names for variables, functions, and classes should not be secondary to the design of a program. Making the code fit in fewer lines -- that should be secondary.
Yeh, post #22 is a long time ago, I learn a lot since. I thought you comment on post #46 the final version. It's very close to what you want to be.

I really thought I made the names a lot better. Like caseA() stands for what the user type in 'a' to choose adding a name. It is in a switch-case part of the code. I call the header file fileVector exactly what it is doing, working on both file and vector. In my mind, this is as clear as it can.

This is the first time in 4 months I have not even studied a page for two days. I actually questioning whether I want to continue to study C++. I feel very frustrated with it when I read about friends, now Memberwise Assignment and Copy Contruction. It's like the language want to be straight.....then when it comes to something inconvenient, then create a back door to bypass it!!! Specially like the friend thing. I thought it's a good practice to have control of the traffic flow having private and all. BUT than you open the back door when it is inconvenient. Then the Memberwise Assignment, just type an extra line to assign the variables!!! Why make it so confusing. BUT, if I don't learn it, I won't be able to understand what other people write.

I peeked into the overload section, sounds like it want to use the operator differently with definitions. I don't know the detail, but that is so so discouraging to me. It's is like playing tricks to make the code looks simpler and save a line of two. I don't know how much knowledge I consider in C++. I am only 1 chapter from completing the whole book(the brief version). I was very excited studying chapter 13 on classes, but 14 looks to be all the tricks. I am questioning whether programming is for me or not. I hope I can finish to chapter 16 in the complete book( that has 20 lessons) on library and templates, but it's just getting harder to concentrate with all these in my mind. I feel very frustrated at this point.

Thanks so much for your help in the last few months.
 
Last edited:
  • #71
34,265
5,903
I really thought I made the names a lot better. Like caseA() stands for what the user type in 'a' to choose adding a name. It is in a switch-case part of the code. I call the header file fileVector exactly what it is doing, working on both file and vector. In my mind, this is as clear as it can.
In both cases above, your choices describe how something is implemented rather than what the symbol is supposed to represent. "caseA" used four letters to represent the keyword, but only one letter to convey that idea that you're going to add something. What should be emphasized is the adding part, not the keyword used in some switch statement.
I feel very frustrated with it when I read about friends, now Memberwise Assignment and Copy Contruction. It's like the language want to be straight.....then when it comes to something inconvenient, then create a back door to bypass it!!! Specially like the friend thing. I thought it's a good practice to have control of the traffic flow having private and all.
It is good practice to control access via the access specifiers. I don't have any good reasons why you should spend any time on learning about friend functions or classes.
Memberwise assignment and copy construction are important if you have a class whose members are pointers to memory somewhere. If you want to have a copy of something that is its own object, rather than just copy the values of the pointers, these are useful topics.
I peaked into the overload section, sounds like it want to use the operator differently with definitions. I don't know the detail, but that is so so discouraging to me. It's is like playing tricks to make the code looks simpler and save a line of two.
If you want to make it so that a class you create can be inserted into a stream or extracted from a stream, the same way that integers, floats, and the basic types can, it's useful to overload the << and >> operators.
If being able to join two objects together makes sense in your application, the you might consider overloading the + operator (this is done for the std::string template class).
I was very excited studying chapter 13 on classes, but 14 looks to be all the tricks. I am questioning whether programming is for me or not. I hope I can finish to chapter 16 in the complete book( that has 20 lessons) on library and templates, but it's just getting harder to concentrate with all these in my mind. I feel very frustrated at this point.
Class design is a subject all its own, and there are many books written on it out there. A search for "c++ design patterns" would probably turn up a lot of hits. We've been trying to get across to you some of the things that make a good design, and some that don't. It's not something you can learn in a month.
 
  • Like
Likes sysprog and yungman
  • #72
pbuk
Science Advisor
Gold Member
1,735
628
Regarding indentation, instead of
C++:
void fileVector::createFile()
  { DirFile.open("Directory.dat", std::ios::out | std::ios::binary | std::ios::app);
    DirFile.close();
  }
write
C++:
void fileVector::createFile() {
  DirFile.open("Directory.dat", std::ios::out | std::ios::binary | std::ios::app);
  DirFile.close();
}
This takes up less space on the page than your version and is clearer and easier to work with (it is called the 'one true brace' style and is the preferred style of many programmers in many languages).

Look at these two statements:
C++:
if (choice != tolower('q')) return;
if (tolower(choice) != 'q')) return;
Which one is similar to something written in the book?
 
Last edited:
  • Like
Likes yungman
  • #73
Vanadium 50
Staff Emeritus
Science Advisor
Education Advisor
2019 Award
25,633
8,816
I don't think better bracing would be high on my priority list. I think some of your earlier points, while all good, are more important than others.

It is not clean to hard code the same filename in 6 different places.
Absolutely agree. I disagree with yungman's "It's not wrong". It is wrong and works only by accident. Explictly naming a file in 6 different places tells the compiler you want to work with 6 different files.

It is not clean to use cryptic method names like caseA.
Couldn't agree more. Method (and variable) names should be clear to you, Future You, and anybody else who works on the code, including people you ask for help.

It is not clean to lay your code out randomly:
  1. sometimes placing a { in the same column as the previous statement, sometimes with 1, 2 or 4 additional spaces of indentation
  2. sometimes placing the next statement on the next line, sometimes on the same line as the { after 0, 1, 2 or 3 spaces
  3. etc. etc.
I agree. Some of these cause more trouble than others. Placing a cin.ignore on the same line after a read probably contributed to not identifying it as the culprit for a downstream cin. And while there are several reasonable styles for brackets and indentations, it is far better to pick with one and stick with it (even if it is "wrong") than flipping back and forth.

It is not clean to write a comment "Assume file is OPEN already" and 2 lines later open the file.
Who could argue with that?

  • It is not clean to mix PascalCase and camelCase randomly for variable names.
  • It is not clean to mix snake_case and camelCase randomly for method names (are you trying to achieve a record with sort_firstName?)
  • It is not clean to use PascalCase for variable names and camelCase for class names (it IS clean to do this the other way round).
These are fairly low priority for me. I would much rather have understandable method and variable names with case style all over the place than incomprehensible variable names that strictly follows a given style.

It is not clean to write tolower('q').
That is true. I do not believe that it is in the book this way, and if it is, it is an error that the student should recognize as such.

The general string handling could use some work. If the program asks "Are you sure?" and the user types "ynnnnnnNNN", do you really want the program to interpret that as a yes?

It is not clean to try to open the same file twice, do you think the computer tries harder to find it the second time?
I laughed when I read this.
 
Last edited:
  • Like
Likes Mark44
  • #74
Vanadium 50
Staff Emeritus
Science Advisor
Education Advisor
2019 Award
25,633
8,816
"caseA" used four letters to represent the keyword, but only one letter to convey that idea that you're going to add something. What should be emphasized is the adding part, not the keyword used in some switch statement.
I thought about this for a while, because I couldn't figure out what was bugging me. (on top of what has been said previously) On top of all the previously mentioned issues, a variable name like CaseA breaks encapsulation, at least psychologically. It doesn't describe what it is, or what it does. It doesn't even describe how it's used, which would be bad enough. It describes when it is called.

That's not part of the object. It's not even a stable part of the calling routine: the name refers to the way it is called today, but not necessary the (only) way it will be called in the future.

There is an art to variable and method naming, that's for sure. It's not reasonable to expect to get everything right the first time. But the wise beginning programmer will listen to people with more experience.

Similarly DirV describes the implementation of the set of Directory objects, thus mixing interface and implemenation. Imagine a future discussion "It's called DirV because it used to be a vector of Directory entries?" "So it's a vector?", "No. It used to be a vector. Then we changed it to a list". "Oh, so it's a list of Directory objects?" "No, we changed it again to a binary tree. And it's not a set of Directory objects, it's a set of Directory entries."
 
Last edited:
  • Like
Likes pbuk
  • #75
pbuk
Science Advisor
Gold Member
1,735
628
Similarly DirV describes the implementation of the set of Directory objects, thus mixing interface and implemenation. Imagine a future discussion "It's called DirV because it used to be a vector of Directory entries?" "So it's a vector?", "No. It used to be a vector. Then we changed it to a list". "Oh, so it's a list of Directory objects?" "No, we changed it again to a binary tree. And it's not a set of Directory objects, it's a set of Directory entries."
Your turn to make me laugh 🤣
 

Related Threads on Help in my program using Classes

Replies
9
Views
1K
Replies
42
Views
4K
Replies
9
Views
8K
Replies
2
Views
2K
  • Last Post
Replies
9
Views
25K
Replies
7
Views
3K
Replies
8
Views
2K
  • Last Post
Replies
1
Views
2K
Replies
1
Views
2K
Top