why is << operator not recognized?

Jun 28, 2010 at 3:31am
I have been trying to write a quiz-making/quiz taking program (super-simple, uses cout stuff etc.) and for some reason I get...
"Error: no operator "<<" matches these operands"
...on lines 38 through 42, on the first << operators.

Here is the code...
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
#include <iostream>
using namespace std;

class Err; //not yet defined
class Question;

int main(){

}

class Question{
public:
	//START OF STANDARD CONSTRUCTOR
Question(const string* Question, //Question
	const string* Hint,      //Hint
	const string* Option1,   //First option
	const string* Option2,	 //Second option
	const string* Option3,   //Third option
	const string* Option4,	 //Fourth option
	const    int* Answer,    //Correct answer number
	const    int* Qnumber){  //Question number
		//Variable value assignments
		question = Question;
		    hint = Hint;
		 option1 = Option1;
		 option2 = Option2;
		 option3 = Option3;
		 option4 = Option4;
	      answer = Answer;
		 qnumber = Qnumber;
	}
	//END OF STANDARD CONSTRUCTOR

	//Standard presentation procedure for questions, returns true if correct answer was given
	bool askQuestion(){
		bool correct;
		cout << "Question number " << *qnumber << "..." << endl
		     << *question << endl << endl 
		     << *option1 << endl    //HERE VISUAL C++ EXPRESS DOES NOT 
		     << *option2 << endl    //RECOGNISE MY USE OF THE "<<"
		     << *option3 << endl    //OPERATOR! AM I USING THE WRONG
		     << *option4 << endl;   //CLASSES?

	}
	
protected:
	//Member variables
	const string* question;  //Question
	const string*     hint;  //Hint
	const string*  option1;  //First option
	const string*  option2;	 //Second option
	const string*  option3;  //Third option
	const string*  option4;  //Fourth option
	const    int*   answer;  //Correct answer (number only)
	const    int*  qnumber;  //Question number
}
Jun 28, 2010 at 3:49am
I am wondering, that your VSE does not moan the unexpected end of file due to the lack of the class-delimiting ';'...


WIth the string-stuff YOu have two options...

Either you do stringobject->c_str() on your question and options (instead of *stringobject)... Or You #include <string> in which the << >> operators are overloaded for the string class...
Jun 28, 2010 at 7:26am
@soccermiles

There really is not much point in using string* rather than just plain string. Same with int.

If you want to do stuff with the string you need to #include <string>.

Also if you have a list of options you might want to look at <vector>:

http://www.cplusplus.com/reference/stl/vector/

1
2
3
4
5
6
#include <string>
#include <vector>

std::vector<std::string> options;
options.push_back("Possible answer 1");
options.push_back("Another possibility");


Jun 28, 2010 at 12:51pm
A vector doesn't have a built-in method for asking questions, and I am using pointers for fun (I want to make a habit of using them so that later when I am doing truly advanced things, I won't still be getting used to them). Also: I AM having trouble understanding references (every time I tried to use them in that program it had similar errors where it didn't understand an operator I was using).

EDIT: Also...what is class delimiting??
When should I pass references and when should I pass pointers to functions?
Last edited on Jun 28, 2010 at 1:16pm
Jun 28, 2010 at 12:56pm
Pointer for fun eh? Hehehe...
Jun 28, 2010 at 1:39pm
soccermiles wrote:
Also...what is class delimiting??


It marks the limits of the class. Class declarations in C++ need to end with a semi-colon:

1
2
3
class Q
{
}; // note the ';' to end the class 


soccermiles wrote:
When should I pass references and when should I pass pointers to functions?


Pass pointers when you want to have fun... ;o)

But normally pointers should really be avoided if possible. However the task will usually lend itself to either one or the other. A rule of thumb is to use a reference unless you have to use a pointer. But sometimes pointers make more sense.

When passing objects as parameters to functions, the preferred option is to pass a const reference like this:

 
void func(const std::string& name);


This ensures that the variable passed in to the function is safe from modification by the function. Also its more efficient than passing a copy:

 
void func(std::string name);


And it is less dangerous than passing pointers.

If you want the function to modify the variable that you pass in, then you can use a non-const reference:

 
void make_uppercase(std::string& name);


You might end up working with pointers. If you need to store non-copyable objects in a container, for instance, you would need to store pointers to them. In that case I would still be tempted to write my functions to accept references and simply dereference the object pointer when I called the function:

1
2
3
4
5
6
7
8
9
10
11
12
13
void func(const MyType& m)
{
    // .. do stuff with m
}

int main()
{
    MyType* mp = new MyType;

    func(*mp);

    delete mp; // remember to clean up ...
}


That keeps my interfaces as pointer free as possible.
Last edited on Jun 28, 2010 at 1:40pm
Jun 28, 2010 at 1:48pm
soccermiles wrote:
I want to make a habit of using them so that later when I am doing truly advanced things, I won't still be getting used to them


Truly advanced programmers avoid pointers like the plague...

Having said that they also end up using them an awful lot and need to understand them intimately.

But if you introduce pointers in everything you do it is possible you will miss out on learning best practice and introduce lots of bad habits. What I would recommend is that you give yourself specific pointer-related tasks in order to learn how pointers work in-depth. But for other things try to use best practice and use the most appropriate form for the given situation.
Jun 28, 2010 at 3:12pm
TY for da info on delimiting.
Exactly how efficient is passing references?
Why is it dangerous to use pointers?

EDIT: Also: What about classes that use pointers to references that were given to them in the constructor? Would that work, or would that cause FATAL ERROR 809942?
Last edited on Jun 28, 2010 at 3:13pm
Jun 28, 2010 at 4:02pm
Passing references is just as efficient as passing pointers.

Not sure about most people but for me the headache with pointers is that every time you create a pointer with new you should call delete once the object will no longer be used, otherwise you risk memory leaks. It's quite easy to forget and i've often spent too long looking for memory leaks. Also sometimes it akward to know when it's safe to delete things. However sometimes, like it's been said above, code may just lean itself better to using pointers as opposed to using references. I find that when i want an object created in a function to have a longer lifetime than the function i need to use pointers, but this is probably not the best example.
Jun 28, 2010 at 4:10pm
I find the ability of pointers to keep your heap data organized attractive. =)

EDIT: And what about my question about pointers to references? If I pass a reference of an object to a constructor, is it a bad idea to use pointers to that reference in the class that I'm constructing? FINE!! I WILL GIVE YOU AN EXAMPLE!!

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
class Question{
public:
	//START OF STANDARD CONSTRUCTOR
	   Question(const string& Question,  //Question
				const string& Hint,		 //Hint
				const string& Option1,   //First option
				const string& Option2,	 //Second option
				const string& Option3,   //Third option
				const string& Option4,	 //Fourth option
				const    int& Answer,    //Correct answer number
				const    int& Qnumber){  //Question number
		//Variable value assignments
		question = &Question;
		    hint = &Hint;
		 option1 = &Option1;
		 option2 = &Option2;
		 option3 = &Option3;
		 option4 = &Option4;
	      answer = &Answer;
		 qnumber = &Qnumber;
	}
	//END OF STANDARD CONSTRUCTOR

	//Standard presentation procedure for questions, returns true if correct answer was given
	bool askQuestion() throw(Err){
		int input;
		bool correct;
		cout << "Question number " << *qnumber << "..." << endl
		     << "Question: " << *question << endl << endl 
			 << "1: " << *option1 << endl 
			 << "2: " << *option2 << endl 
			 << "3: " << *option3 << endl 
			 << "4: " << *option4 << endl;
		cin >> input;
		if(input == *answer){
			correct = true;
		}else correct = false;
		return correct;
	}
	
protected:
	//Member variables
	const string* question;  //Question
	const string*     hint;  //Hint
	const string*  option1;  //First option
	const string*  option2;	 //Second option
	const string*  option3;  //Third option
	const string*  option4;  //Fourth option
	const    int*   answer;  //Correct answer (number only)
	const    int*  qnumber;  //Question number
};
Last edited on Jun 28, 2010 at 4:13pm
Jun 28, 2010 at 4:47pm
soccermiles wrote:
Also: What about classes that use pointers to references that were given to them in the constructor? Would that work, or would that cause FATAL ERROR 809942?


That sounds a bit dangerous. So you have to be careful. If the class is designed to use pointers internally then I think it would be wise for it to ask for pointers in the constructor. Otherwise it could be making assumptions about the things being passed into it that may well not be true. At least if the class asks for pointers the caller can avoid passing things in that will go out of scope. That being said, the class interface should be documented and let you know of any potential problems.

With respect to references it is also a bit dangerous for a class to hold a reference to an outside object. Unless the class is designed to do that all sorts of problems can occur if the outside object goes out of scope.

When you pass something in to the constructor, then, I think you need to either copy it or use what you want from it and discard it. If you want to hold a reference/pointer to it then it should be part and parcel of the way the class is designed to work.

So don't go round willy-nilly doing things like this for efficiency:

1
2
3
4
5
6
7
class Danger
{
    const std::string& _name;
    const std::string* _addr;
public:
    Danger(const std::string& name, const std::string& addr): _name(name), _addr(&addr) {}
};


Jun 28, 2010 at 4:51pm
soccermiles wrote:
FINE!! I WILL GIVE YOU AN EXAMPLE!!

Yes, that's very very bad. I recommend not storing pointers. Just take a copy like this:

1
2
3
4
5
6
7
class Safe
{
    std::string _name; // will be a copy of the passed in reference.
public:
    Safe(const std::string& name) : _name(name) {}
};
Last edited on Jun 28, 2010 at 4:53pm
Jun 28, 2010 at 5:34pm
But if it is passed in reference and then stored in a string, that means it has to copy each string once (Increases running time). Maybe I'm just freaking out about this because I learned C++ using textbooks organized around execution speed and memory conservation...

(Basic C++ Through Game Programming, 3rd edition)
(Introduction to Algorithms by MIT)

EDIT: I also have an awsome book called "Game Coding Complete, 3rd edition", but it is WAYYY to advanced for me. I am still stuck on how to draw a circle in a window. =(
Last edited on Jun 28, 2010 at 5:36pm
Jun 28, 2010 at 5:52pm
But if it is passed in reference and then stored in a string, that means it has to copy each string once (Increases running time).


Not if strings are refcounted (which they generally are). Copying them is cheap since the string data isn't really copied.

One of the problems with using pointers is that the original string must exist for the lifetime of this Question object. If the source string disappears, then all of your pointers become bad and your Question class explodes.

Also, copying an integer is just as fast as (or faster than) copying a pointer to an integer. So keeping an int* instead of an int doesn't make a lot of sense.

Also accessing an int* is slower than accessing an int because it requires indirection.
Jun 28, 2010 at 5:56pm
I wouldn't worry about std::string. It actually maintains a pointer internally. So when it gets copied it is only the pointer that is copied and not every single character. The characters are only copied if you actually modify the string.

If you are liberal with const then passing strings around is very efficient. Also C++ is very good at optimising copying away when its not truly needed.

Actually because of another question on this forum I did some testing and passing an int by reference and by copy generated exactly the same code. The compiler figured that the copy did not need to take place and so it didn't do it. So its better to not worry about copying too much.

Generally speaking what you store inside your class should not be reference but copies. However, what you pass as variables to functions should be const references if at all possible.

Except for basic types like int and double, then just take copies. Its just as efficient as a reference.

When it comes to speed it is important to be efficient when and where it makes a difference. Constructing objects is not always where its at for that. It is how they perform during repeated operation inside a loop that will actually make a difference.
Last edited on Jun 28, 2010 at 5:59pm
Jun 28, 2010 at 6:05pm
So if I was making a program that did sorting operations, THEN I might want to worry about using references and pointers instead of copying?
Jun 28, 2010 at 6:10pm
Yes.

If you had a lot of large objects stored in some container that needed to be sorted, then it would make good sense to store only their pointers in the container and so only their pointers would be copied in the sort process.

I don't think references would really be useful in that scenario.

They are good for passing large objects into functions.
Topic archived. No new replies allowed.