Why use polymorphism for grading activities?

  • Thread starter Thread starter yungman
  • Start date Start date
Click For Summary
Polymorphism in grading activities allows for different grading schemes, such as letter grades and pass/fail outcomes, to be handled through a common interface. The discussion highlights a specific implementation issue where a function intended to display grades defaults to the base class's grading method instead of the derived class's method. By changing the function parameter to accept the derived class type, the correct grading method is invoked. The conversation also emphasizes the importance of virtual functions in enabling this flexibility and the potential for confusion when examples do not clearly illustrate their purpose. Overall, understanding polymorphism is crucial for effectively managing different grading systems in programming.
  • #31
Mark44 said:
Just to be clear, I believe yungman's complaint was about overloading operators, not function overloads.
Some statements in that post specified operators, but others didn't, including the first statement. So I wasn't sure about that. I have a particular dislike for operator overloading but I can also see the advantage in the judicious use of it.
 
Technology news on Phys.org
  • #32
@Youngman, one concept that is worth learning is the DRY principle. It seems sometimes you are asking us why we need a DRY solution when we can easily make a simple WET solution.

DRY solutions sometimes take more careful thought, engineering, and initial effort, than WET solutions, but there are a lot of advantages. The quick and easy route isn't always the best route.

Don't repeat yourself (DRY, or sometimes do not repeat yourself) is a principle of software development aimed at reducing repetition of software patterns,[1] replacing it with abstractions or using data normalization to avoid redundancy.
...
When the DRY principle is applied successfully, a modification of any single element of a system does not require a change in other logically unrelated elements. Additionally, elements that are logically related all change predictably and uniformly, and are thus kept in sync.
...
Violations of DRY are typically referred to as WET solutions, which is commonly taken to stand for "write every time", "write everything twice", "we enjoy typing" or "waste everyone's time". [4][5][6]

https://en.wikipedia.org/wiki/Don't_repeat_yourself
 
  • #33
Jarvis323 said:
@Youngman, one concept that is worth learning is the DRY principle. It seems sometimes you are asking us why we need a DRY solution when we can easily make a simple WET solution.

DRY solutions sometimes take more careful thought, engineering, and initial effort, than WET solutions, but there are a lot of advantages. The quick and easy route isn't always the best route.
https://en.wikipedia.org/wiki/Don't_repeat_yourself
Actually I am more looking for reason why using certain things in a macro point of view, DRY or WET is secondary. I won't be convince just saving a few lines only.

Remember I don't know real life programming, all I get in the book is how to make things "looks" easier using overloading. And even in Polymorphism, it's not very clear...Until reading the post from Mark and jedishrfu giving example in the big picture how Polymorphism really help to add more classes and use the same commands to call functions. That's when I really see the usefulness of Polymorphism.

For example, I can write a base class Travel, then I can have derived class "byWalk", "byDriving", "byPlane", "byRocket" etc. Then I can have member function go(destination) in every one of them. I then use a Travel*tptr to do tptr->go() to point to anyone of the derived class.

Say if you call go(mars) in byRocket class, you return (cout << " call Elon Mask" << endl); If you call go(mars) in byWalk class, return (cout << :biggrin: :biggrin::biggrin: << endl;). You can add more derived classes as will and will not affect all the existing ones. This is the key and most convincing reason for me, forget DRY or WET. Even if I have to write 100 extra lines of code to make it happens, it's worth it.I really want to hear about the real life usefulness of overloading in the macro world, not just make it easier to read. I can care less whether I write a few more or few less lines.
 
  • #34
yungman said:
Even if I have to write 100 extra lines of code to make it happens, it's worth it.
yungman said:
I really want to hear about the real life usefulness of overloading in the macro world, not just make it easier to read. I can care less whether I write a few more or few less lines.
You need to be more specific -- I believe you are talking about overloaded operators, right?

From post #25, which you might have missed...
Mark44 said:
One thing I don't think you realize is that there are different programmer roles. In one role, a programmer develops classes (or libraries or APIs); a different end-user programmer potentially would use those classes. In contrast, you've been writing the whole program -- whatever classes are called for, and main() where the classes get instantiated and used. In real life, with large programs, a team of developers produces a set of classes that end users use to create their own programs. Typically the development team comes up with features to make the API more attractive to the end-user buyers. Including the convenience of overloaded operators is part of what could make the API more attractive.

It doesn't matter if the API developer has to type a few more lines of code to add a feature like an operator overload. What matters is that the convenience to the end-user, who doesn't have to re-invent the wheel each time he needs to perform some operation.
... and doesn't need to retype the code that is present in the overloaded operator.

Repeating myself, you seem to be making a big deal unnecessarily about overloaded operators, thinking that they are overly complicated. They really are just functions with a slight twist, mostly about whether they should return an object or a reference to an object.
 
  • Like
Likes Vanadium 50 and yungman
  • #35
I am excited about C++ for once! All of a sudden, things seems to come together, I am starting to see the reason of all these fancy stuffs. Stuffs starting to make sense( not in the sense of knowing how to use them, more the REASON for using them).

Chapter 15 has been going quite smooth other than the array of pointers that hung me up a little( it's resolved). About 14 more pages to go in this last chapter and I am done with the Brief version of Gaddis from cover to cover! It's time to chill the champion! Reaching a mile stone, ready for the next chapter. Thank to all you guys helping.

It's getting easier lately, the first 3 months was the hardest, those were the dark days when I didn't understand the names, the terms. Read online, didn't understand, when you guys tried to explain, didn't understand. Now, I am a lot more familiar with the names, things are just a lot easier even the subject gets a lot harder as it progresses.

Thanks
 
  • Like
Likes FactChecker
  • #36
@yungman, inasmuch as there was some discussion in this thread about overloading, I though I would throw in an example that is somewhat in the same vein, in which multiple versions of two functions are created at compile time.

This is really about template functions, a topic you probably haven't seen yet.
C++:
// TemplateFn.cpp - Example of a templatized function
#include <ccomplex>
#include <iostream>
using std::complex;
using std::cout;
using std::endl;

template <class T>                // Template function for sum
T sum(T a, T b) { return a + b; }

template <class T>                  // Template function for product
T prod(T a, T b) { return a * b; }int main()
{
    // Create three instances of each template function
    int a = 3, b = 5;
    // Call sum() and prod() with int arguments
    int intRet1 = sum<int>(a, b);
    int intRet2 = prod<int>(a, b);
    cout << "Integer sum: " << intRet1 << " product: " << intRet2 << endl;

    double c = 2.5, d = 3.8;    
    // Call sum() and prod() with double arguments
    double dblRet1 = sum<double>(c, d);
    double dblRet2 = prod<double>(c, d);
    cout << "Double sum: " << dblRet1 << " product: " << dblRet2 << endl;

    complex<double> e = { 2.5, 3.0 }, f = { 6.0, -2.0 };
    // Call sum() and prod() with complex arguments
    complex<double> cmplxRet1 = sum<complex<double>>(e, f);
    complex<double> cmplxRet2 = prod<complex<double>>(e, f);
    cout << "Complex sum: " << cmplxRet1 << " product: " << cmplxRet2 << endl;    
}

Output:
Code:
Integer sum: 8 product: 15
Double sum: 6.3 product: 9.5
Complex sum: (8.5,1) product: (21,13)
In the last line, the sum is 8.5 + 1i, and the product is 21 + 13i, the usual notation for complex numbers that mathematicians use.
 
  • Informative
  • Like
Likes sysprog and FactChecker
  • #37
As I think I mentioned in another thread, another important use for operator overloading is when you've defined some object and you want to be able to use it with a standard container such as inserting it into a std::set or using it as a key for std::map. In order to do that, operator< needs to be defined for your object. (If you use the unordered versions of these containers, then you don't need operator<, but you need to write a hash function, which is at least as much work.)
 
  • Like
Likes sysprog

Similar threads

  • · Replies 23 ·
Replies
23
Views
2K
  • · Replies 17 ·
Replies
17
Views
2K
  • · Replies 35 ·
2
Replies
35
Views
4K
  • · Replies 89 ·
3
Replies
89
Views
6K
Replies
5
Views
2K
Replies
10
Views
2K
Replies
10
Views
2K
  • · Replies 75 ·
3
Replies
75
Views
6K
Replies
6
Views
2K
Replies
3
Views
2K