Someone posed an assignment question on beginners forum which I thought I'd have a go at. For some reason my class file compiles fine, but when I try to make the executable with main() it complains of an :
undefined reference to gotInteger(basic_istream<char, char_traits<char> >&, int&)
collect2, ld returned status 1
I don't understand why the object file compiles fine but the executable won't. Makes no sense to me.'code is as follows.
// Simple program to process a file
// full of integers.
#ifndef PROCINT_H_
#define PROCINT_H_
#include <iostream>
using std::cout;
using std::cin;
using std::endl;
using std::cerr;
using std::istream;
#include <string>
using std::string;
#include <cstdlib>
using std::exit;
#include <fstream>
using std::ifstream;
class procint
{
public:
procint(string input);
~procint();
void setInputFile(string infl);
string getInputFile();
void processFile();
bool gotInteger(istream& is, int& i);
void sortArray();
private:
// change depending on file size.
conststaticint ARRSIZE=100;
int myArray[ARRSIZE];
string inFile;
};
#endif
commenting out the lines:
while (gotInteger(theFile, i))
{
myArray[count++] << i;
}
it compiles fine. :s I don't get it, something wrong with my logic?
Because the compiler and the linker allow declared but undefined functions as long as there are no calls to them and no one tries to get their address.
By the way, I see no reason for gotInteger() to be a member function. There are no references to this anywhere in that function.
the way i see it is, istream& is, int& t are being passed by reference, whereas the values I pass them from processFile(), only exist within the scope of processFile() so why would I need to use this keyword?
The keyword this represents a pointer to the object whose member function is being executed. It is a pointer to the object itself.
One of its uses can be to check if a parameter passed to a member function is the object itself.
It is also frequently used in operator= member functions that return objects by reference (avoiding the use of temporary objects).
In fact this function is very similar to the code that the compiler generates implicitly for this class if we do not include an operator= member function to copy objects of this class.
I would have thought going by that last comment in the tutorial, that it is done anyway. and being that I am only returning true or false... there's no point using keyword this.
Additionally I don't understand why you are both implying member functions need this does that mean my constructor, my sort, and processFile all my sets and gets all need to use this as well?
What is so different about this function compared to others?
What we're trying to say is that there's no point in procint::gotInteger() being a member function. If you were to remove the procint:: from the definition and remove the declaration from the class definition, the program would still compile. When that happens it's because the function doesn't make neither implicit nor explicit use of the this pointer, which means the function shouldn't be member of a class.
See this example:
1 2 3 4 5 6 7 8 9
struct A{
int a;
void f1(){
a++; //(implicitly: this->a++;)
}
int f2(){
return rand();
}
};
A::f2() shouldn't be a member of A because it doesn't use this implicitly or explicitly. You're passing a useless parameter to call it:
1 2 3 4
A o;
o.a=0;
o.f1(); //o is passed as this
o.f2(); //o is passed as this, even though f2() doesn't need it
Obviously, this isn't a performance problem. Passing a pointer is almost insignificant. Instead, it's a design problem. You're putting interfaces where they don't belong.
What we're trying to say is that there's no point in procint::gotInteger() being a member function. If you were to remove the procint:: from the definition and remove the declaration from the class definition, the program would still compile.
I don't think it would unless I removed or changed the while loop as well.
A::f2() shouldn't be a member of A because it doesn't use this implicitly or explicitly. You're passing a useless parameter to call it:
I still don't understand how what I'm doing is considered useless...
// i call gotInteger using cin, i
// istream& is, is a reference to cin. (where 'cin' buffer exists in memory)
// int& i, is a reference to i (where 'i' exists in memory)
bool procint::gotInteger(istream& is, int& i)
{
// this function:
// if an integer could be extracted then
// true is returned and so is the integer
// otherwise
// false is returned and no integer is returned
// This routine consumes and discards non-integer chars,
// hence it changes the state of the stream by always moving
char c;
while (true)
{
is >> i; // cin >> i
if (is.good()) returntrue;
if (is.eof()) returnfalse;
if (is.bad()) returnfalse;
// must clear junk
is.clear();
is >> c; // clears bad char.
cout << "Bad int=[ " << c << " ]" << endl;
}
-----------------
Obviously, this isn't a performance problem. Passing a pointer is almost insignificant. Instead, it's a design problem. You're putting interfaces where they don't belong.
I guess the reason I don't understand is the confusion between this and this in java. I can't really see where this in C++ would be that useful. Whereas in java I use it constantly because it points to the class fields, hence is used in most acsessors. Also I still don't fully grasp why you use it in C++.
Don't worry about it though you have explained it enough, yet I still don't seem to grasp it, so I can put it off for a week or two and come back to it. If I still need further clarification then I will ask in a different post.
i think perhaps the main reason I don't quite get it is your samples make sense, however I can't see the relevance between my method and your samples.
Thanks for your help guys.
#include <iostream>
using std::cin;
using std::cout;
using std::istream;
#include <string>
using std::string;
bool gotInteger(istream& is, int& i);
////////////////////////////
int main()
{
cout << "Enter words intermixed with integers ... EOF stop\n";
int i;
while (gotInteger(cin, i))
cout << i << '\n';
}
//Purpose: extract and return integer from an input stream
bool gotInteger(istream& is, int& i)
{
char c;
while(true)
{
is >> i;
if (is.good()) returntrue;
if (is.eof()) returnfalse;
if (is.bad()) returnfalse;
//
is.clear();
is >> c;
}
}
it's not a class, it's just a program that does random things, so it's fine....???