0

This might seem like a silly question to the more seasoned C++ coders out there, but I thought once you have a class and you create an object of that class, you call a public method of that class using the object you created (unless it is a static method, in which case you call it either using an object or the class name itself)?

Then why does this work?

Function definition:

template <typename Object>
void printList(const List<Object>& theList) {
    if (theList.isEmpty())
        cout << "Empty list!" << endl;
    else {
        ListItr<Object> itr = theList.first();
        for(; !itr.isPastEnd(); itr.advance())
            cout << itr.retrieve() << " ";
    }

    cout << endl;
}

Function call:

printList(myList);

What am I missing here? How does the rest of the program know that printList() belongs to the class List<int> unless I call printList() using an object of List<int>?

This works too by the way, I just checked. I would have used this way of calling and defining the function. Note that this time the function is defined using the this pointer, the way I would have thought it works.

Function definition:

template <typename Object>
void List<Object>::printList() {
    if(this->isEmpty())
        cout << "Empty list!" << endl;
    else {
        ListItr<Object> itr = this->first();
        for(; !itr.isPastEnd(); itr.advance())
            cout << itr.retrieve() << " ";
    }

    cout << endl;
}

Function call:

myList.printList();
Lightness Races in Orbit
  • 378,754
  • 76
  • 643
  • 1,055
Ambidextrous
  • 810
  • 6
  • 14
  • 1
    `How does the rest of the program know that printList() belongs to the class List` Does it? Why does it take a `List` as a parameter, then? Looks to me like you created a free function, not a member function... especially since when you _do_ create a member function in your second example, your show with your usage of `List::` that you're doing these function definitions outside of a class definition. – Lightness Races in Orbit Mar 02 '12 at 18:55
  • Because ... that's *not* a method in a class. It's a simple function. – Brian Roach Mar 02 '12 at 18:58
  • Thanks - I fixed that and made the first one a member function; and now it needs the object to be able to be called. Still seems strange why it needs the object also passed as a parameter when the same can be done with using 'this'. – Ambidextrous Mar 02 '12 at 19:02
  • @Ambidextrous: If it's a member function, then it _doesn't_ need the object passed as a parameter, and you shouldn't do that. Which C++ book are you using? – Lightness Races in Orbit Mar 02 '12 at 19:04
  • @Ambidextrous: The non-member needs a parameter because there is no `this` - you only get that in non-static members. The member doesn't need a parameter - as you say, it gets passed `this` implicitly. – Mike Seymour Mar 02 '12 at 19:06
  • @LightnessRacesinOrbit - 'Data Structures & Algorithm Analysis in C++' - Mark Allen Weiss, Ed 2. – Ambidextrous Mar 02 '12 at 19:07
  • @Ambidextrous: [Never heard](http://jcatki.no-ip.org/fncpp/Resources) [of it](http://stackoverflow.com/questions/388242/the-definitive-c-book-guide-and-list) – Lightness Races in Orbit Mar 02 '12 at 19:22
  • If the example came straight from a book, why did you need to edit it? Which matches the actual content of the book, before the edit or after? – Mark Ransom Mar 02 '12 at 21:51
  • @LightnessRacesinOrbit, Amazon has: http://www.amazon.com/Data-Structures-Algorithm-Analysis-Edition/dp/032144146X/ref=sr_1_1?ie=UTF8&qid=1330725129&sr=8-1 – Mark Ransom Mar 02 '12 at 21:53
  • 1
    @Ambidextrous: By editing your question in this way, you have _completely and fundamentally changed it_, rendering all the answers completely useless. **Please do not do that.** – Lightness Races in Orbit Mar 03 '12 at 02:26
  • @MarkRansom: So what if Amazon has it? Last I checked, Amazon was not an authority on what is or is not a peer-reviewed and/or professionally-accepted accurate/useful C++ book. – Lightness Races in Orbit Mar 03 '12 at 02:27
  • @MarkRansom: When did I claim that it doesn't exist? I'd appreciate it if you'd stop putting words in my mouth. Thanks. – Lightness Races in Orbit Mar 03 '12 at 02:34
  • @LightnessRacesinOrbit quote: "Never heard of it". My apologies for taking that statement at more than face value, and misrepresenting it. – Mark Ransom Mar 03 '12 at 04:14
  • @LightnessRacesinOrbit, neither Amazon nor I made any claims to it being a *good* book, and we now have some evidence to the contrary. I was just providing a link for those that are as curious as I was. I only aimed the comment at you because it made a counterpoint to your own declaration. – Mark Ransom Mar 03 '12 at 04:23
  • @LightnessRacesinOrbit, I've replaced my comment with something more appropriate and I'll also delete my OT comments once I know you've seen them. Again my apologies. – Mark Ransom Mar 03 '12 at 04:25

2 Answers2

1

Taking a shot in the dark here, but are you expecting the following function to be a member function of T?

void print(const T& someT);

Because it's not. It's just a free function that takes a T.


The following is a class definition and member function declaration (though the member function is silly because it takes an argument that is probably completely redundant):

struct T {
   void print(const T& someT);
};

And the following is the same silly member function defined out-of-line:

void T::print(const T& someT) {
   // ...
}

It's not entirely clear from your question which one you're really doing here, but the first one is definitely not a member function.

Lightness Races in Orbit
  • 378,754
  • 76
  • 643
  • 1,055
  • Thanks - fixed that and made it a member function - I should rephrase my question. It now needs an object in order for the call to be made, still to me the method using 'this' seems sufficient. – Ambidextrous Mar 02 '12 at 19:04
0

Your understanding is correct. Unless you are failing to tell us something important about List<>, or missing some important lesson in the book, the second example is clearly superior to the first.

Then why does this fragment need the object itself to be passed?

Because it is coded that way. Seriously, you'd need to ask the author of that code, who is probably the author of your book.

What am I missing here?

The two examples are not identical. The first one implements "given two List<>s, a and b, ask a to print the contents of b: a.printList(b)". The second implements "given one List<>, a, ask a to print the contents of itself: a.printList().

It is possible that the book's authors are trying to explain that very distinction. I don't know what they are trying to show, I haven't read the book.

Why not just use this?

If you trying to achieve the 2nd objective I listed above, namely allow a List to print itself, you should just use this.

Robᵩ
  • 163,533
  • 20
  • 239
  • 308