Any method (within a C++ class) that prints to a file or to a screen has a return type of void. What role does the keyword void perform?

I understand the application of void to methods (e.g. access and modifier methods)that return a number. In those cases, the number is returned back to the main program and stored in the computer, so the data needs a type to exist. That part is clear.

What I do not understand is the difference between the performance of a print method and other methods. A print method writes the data to an output file. It does not return any data to the main program in a way similar to the access or modifier methods(am i right?) but rather takes an ofstream object as its input and stores data within that object. In that sense, it is returning data to the main program. So shouldn't we replace void with ofstream?

Seems to me that you need to give us a specific code sample and explain what you are asking. Most of what you said is confusing and (I believe) wrong. But because it's confusing I'm not sure.

The void return type can be thought of as nothing more than a place-holder. The general form of a function declaration/definition is:

[I]returnDataType[/I] functionName([argType arg1, [argType arg2, ...]])

The void type is used in the returnDataType position to indicate that there is no return value. This makes sense for a function designed only to produce output, but isn't necessarily the best way to do it.

"This makes sense for a function designed only to produce output":

Am I right to say that

the variable object.method(argument) does not have a return value when the method prints values to a file (as its job is to print, not return values),
but that, since the method is writing to a file and the argument is an output file, the argument should get modified, which is why the ampasand is used to modify the argument (or file) each time the method is implemented in the main program?

P.S.: WaltP, I will be posting on this thread from now on.

Only partially. This particular method does not return a value, but it's not a general rule. Whether a function returns a value or not depends on how it's declared/defined and how it's intended to be used.

Thanks very much!

Let me ask one other question about a constructor I have created.

Here's the code:

// Spherical polar constructor
	threevector(double r, double theta, double phi, char angle_type)
	{
		if ((angle_type == 'd') || (angle_type == 'r'))
		{
			if (angle_type == 'd')
			{
				double pi = acos(-1.0);
				phi *= (pi/180);  
				theta *= (pi/180);
			}
			else
			{}
			
			xcoord = r*sin(theta)*cos(phi);
			ycoord = r*sin(theta)*sin(phi);
			zcoord = r*cos(theta);
		}
		else
		{}
	}

If the constructor call in the main program inputs an angle_type of anything other than d or r, then the threevector returns -9.25596e+061.
Why is that number returned?

That's probably your compiler's representation of Not a Number (NaN).

The way this is written, your xcoord, ycoord, and zcoord values don't get initialized if the input isn't a 'd' or an 'r'. You'll have to find a better way to control that situation.

Edited 5 Years Ago by Fbody: n/a

"You'll have to find a better way to control that situation.":

Why? Isn't the code I have written any good? Sure, it does not return -9.25596e+061 when the input is not a 'd' or an 'r', but that number should signal that something is amiss. Please help me understand the motivation for improving the code and how to go about modifying it.

I've got to pull this over so that it's in this thread, it's getting too difficult to work without it:

#include <iostream> // Include input/output stream
#include <cmath>

class threevector
{

public:
	double xcoord, ycoord, zcoord;
	
	// Default constructor
	threevector()
	{
		xcoord = 0.0;
		ycoord = 0.0;
		zcoord = 0.0;
	}
    
	// Cartesian constructor
	threevector(double x, double y, double z)
	{
		xcoord = x;
		ycoord = y;
		zcoord = z;
	}

	// Method to print out contents to screen
	void print()
	{
		std::cout << xcoord << '\t'
           		      << ycoord << '\t'
				  << zcoord << std::endl;
	}

	//Method to print out contents to file
	void print(std::ofstream fout)
	{
		fout << xcoord << '\t'
			 << ycoord << '\t'
			 << zcoord << std::endl;
	}
	
};

"You'll have to find a better way to control that situation.":

Why? Isn't the code I have written any good? Sure, it does not return -9.25596e+061 when the input is not a 'd' or an 'r', but that number should signal that something is amiss. Please help me understand the motivation for improving the code and how to go about modifying it.

Unfortunately, the way you have written that is less than ideal. I won't say it's not any good, but it's more complex than necessary, making it inefficient.

I would re-work it so that either you only have one (1) if-then ladder instead of 2 nested ones, or use a switch statement:

if (angle_type == 'd') {
  //calculate degree values
} else if (angle_type == 'r') {
  //calculate radian values
} else {
  //apply default values
}

or

switch (angle_type) {
 case 'd':
   //calculate degree values
   break;
 case 'r':
   //calculate radian values
   break;
 default:
   //apply default values
}

Additionally, I would add an input validation loop to your main() (or wherever you instantiate your threevector class from).

char inputValue = '\0';
cout << "Enter either 'y' or 'n': ";
cin >> inputValue;
while (tolower(inputValue)!='y' && tolower(inputValue)!='n') {
  cout << "Invalid input." << endl;
  cout << "Enter either 'y' or 'n': ";
  cin >> inputValue;
}
//instantiate the class

Thanks! I much rather prefer the if-else ladder.

I am wondering if there is a way to print an error message in the

else{}

part of the if-else ladder.

I know, but if I write

outfile << "Mistaken angle type" << std::endl;

where outfile is the name of the object of class ofstream, the code gives an error message.

That's because outfile doesn't exist inside the function (it's not "in scope"). Use the standard output stream (std::cout) to output the error to the console.

Many of your questions are very elementary. I fear you may be getting ahead of yourself trying to fully implement OOP and classes at this point in your progression. It's really not possible to successfully implement much of anything until you properly understand the concept of "scope". Here is a link to a pretty good tutorial. I suggest you start at the beginning and take the time to understand the main topic(s) of each chapter before you move on to the next.

Obviously, it's up to you what you do, but I feel I should bow out of this conversation for the time being so that I don't confuse you more.

Edited 5 Years Ago by Fbody: n/a

This article has been dead for over six months. Start a new discussion instead.