Need function assistance.

Hello, so I am trying to put some code in a function for reuse. My main question is if I should put it in a member function in a class or write it as a normal function.

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
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
  #include <iostream>

#include <string>

#include <fstream>

#include <sstream>

#include <assert.h>

using namespace std;

void getInfo();
class Personal {
  public:
    void setName(string n) {
      name = n;
    }
  void setAddress(string a) {
    address = a;
  }
  void setAge(int a) {
    age = a;
  }
  void setPhone(string p) {
    phoneNum = p;
  }
  string getName() {
    return name;
  }
  string getAddress() {
    return address;
  }
  int getAge() {
    return age;
  }
  string getPhone() {

    return phoneNum;
  }
  private:
  string name;
  string address;
  int age;
  string phoneNum;

};

int main() {
  Personal info;
  string userName;
  string userAddress;
  int userAge;
  string userPhone;
  int choice = 1;
  cout << "Please choose an option: " << endl << "Enter 1 to create new file. Enter 2 to append the file. Enter 3 to read full file" << endl;
  cin >> choice;
  switch (choice) {

  case 1:
    {
     
		getInfo();
		
      ofstream myFile;
      myFile.open("myInfo.txt");
      if (myFile.is_open()) {
        myFile << "Name: " << info.getName() << endl;
        myFile << "Address: " << info.getAddress() << endl;
        myFile << "Age: " << info.getAge() << endl;
        myFile << "Phone Number: " << info.getPhone() << endl;
        myFile.close();
      } else {
        cout << "Unable to open file";
      }
      break;
    }

  case 2:
    {
	  cout << "Enter your name" << endl;
	  cin.ignore();
      getline(cin, userName);
    
      cout << "Enter your Address" << endl;
       cin.clear();
      getline(cin, userAddress);
     
      cout << "Enter your age" << endl;
      cin >> userAge;
    
      cout << "Enter your Phone #" << endl;
      cin.ignore();
      getline(cin, userPhone);
  

      info.setName(userName);
      info.setAddress(userAddress);
      info.setAge(userAge);
      info.setPhone(userPhone);
      
      ofstream myFile;
      myFile.open("myInfo.txt", ios_base::app);
      if (myFile.is_open()) {
        myFile << endl;
        myFile << "Name: " << info.getName() << endl;
        myFile << "Address: " << info.getAddress() << endl;
        myFile << "Age: " << info.getAge() << endl;
        myFile << "Phone Number: " << info.getPhone() << endl;
        myFile.close();
      } else {
        cout << "Unable to open file";
      }
      break;
    }

  case 3:
    {
    string STRING;
	ifstream infile;
	infile.open ("myInfo.txt");
        while(getline(infile,STRING)) // To get you all the lines.
        {
	       // Saves the line in STRING.
	        cout<<STRING << endl; // Prints our STRING.
        }
	infile.close();
	system ("pause");

  }
  return 0;
}
}
void getInfo() {
	
	  string userName;
  string userAddress;
  int userAge;
  string userPhone;
	
	 cout << "Enter your name" << endl;
      cin.ignore();
      getline(cin, userName);
   
      cout << "Enter your Address" << endl;
      cin.clear();
      getline(cin, userAddress);
 
      cout << "Enter your age" << endl;
    
      cin >> userAge;
  
      cout << "Enter your Phone #" << endl;
      cin.ignore();
      getline(cin, userPhone);

      info.setName(userName);
      info.setAddress(userAddress);
      info.setAge(userAge);
      info.setPhone(userPhone);
}


As you can see at the bottom I am trying to use a normal void function to get and set all the data. I am getting one error that says the info.setName(userName); line is not declared in scope. It's not saying anything about the other info.memberFunctions.

Thanks!
Your getInfo() function is using a variable (info) that isn't declared in its scope or at global scope (NOT recommended!)

The easiest way to fix the problem:

1. move the getInfo() function declaration AFTER your Personal class declaration/definition

2. modify getInfo() so it takes a reference to an instance of your Personal class
void getInfo(Personal&); & void getInfo(Personal& info)

3. modify your function call in main() to pass your info variable into the function.

One recommendation, if you are going to be writing C++ code: don't include C library headers. Use <cassert> instead of <assert.h>.

I won't even get into being lazy and sloppy with using namespace std;.

Last edited on
I would make getInfo() a member function and get rid of all the setters unless you have a good reason to keep them.

You didn't indicate what line your error was on, but in function getInfo(), you don't declare info. info is a local variable within main. getInfo() can't see it.

BTW, lines 65-75 and 102-112 are duplicates of each other. That's a good indication that you should should be calling a function.
My rule of thumb here is this:
if you need a function that accepts a class instance, eg
void foo (Personal &p);
that MAY be better served as a free-standing function. It depends on what it does at that point: if what it does is needing access to private members or is doing something that the 'class should do to itself' then it should be a class member. If it is doing something external to the class, it should be stand alone. If it feels like it should be stand-alone but needs private data, you have a design flaw red flag (could be as simple as making a getter/setter for the private variable).

methods like getters and setters are always class members unless you have a very unusual need, and if you do have that unusual need, you wrap the class versions in a public function: do NOT make this functionality external to the class. It takes time to get the 'zen' of this, but after a bit of time you should see why getters and setters are part of 'what a class should do for itself' and not 'external'.
external example might be an exotic 'unique to this user of the class only' formatted output (eg print to screen or print to string) that accepts one instance of the object, calls its 'getters' and formats the data the way you needed it. If this style of printing is reusable, it would have been a class member, but if it were highly specific -- say an xml file for a specific consumer -- it would be an external function.

Again, its hard to explain when something belongs outside the class, but this approach will help you to make the decision and begin to see what I am trying to say.
Jonnin: What I am hearing is that it would be easier and better to make it a class member function. I could probably recode it to just use the private member variables. right?

Furry guy: First off, sorry for my newb-ness. I'm not fully understanding your code. It worked great but I am having trouble understanding how you used a class and class object in a function, and why you had to do that:

This code is confusing me: void getInfo(Personal&); & void getInfo(Personal& info)

Also, how did the info class from the getInfo() function get carried as an argument to the function call? Is it just treated like any other arguement? Would it work if I used a different variable when I call the getInfo() function in main (not info)?

Thank you so much! I am really trying to learn this.
One more thing, you mentioned the using namespace std; - Is there a list or something that states all the areas where you need to use a std::? I know std::cin and std::cout but there are some more obscure ones. I get frustrated with that aspect of using std::. I am looking on google for it too.

Thanks!
For all that is in the std namespace, what you want is a tutorial and reference on the C++ standard library. The list you're asking for is nearly the table of contents for a reference, like that by Josuttis (sp?) on the Standard Library.

At the risk of giving an inappropriate answer:
http://eel.is/c++draft/libraryindex
Last edited on
@mbozzi, now that's a list

I'm particularly fond of the disclaimer in the index (http://eel.is/c++draft/)

Note: this is an early draft. It's known to be incomplet and incorrekt, and it has lots of bad formatting.
Jonnin: What I am hearing is that it would be easier and better to make it a class member function. I could probably recode it to just use the private member variables. right?

yes, and no.
getting and setting of class data is part of a class: almost all modern classes use the getter/setter 'pattern' for lots of reasons, and IN THIS SPECIFIC CASE yes, they belong IN the class. It has nothing to do with easier, this is part of modern object oriented programming concepts (which have nothing to do with c++ directly, you can violate them and have working code all day long). Its not a language thing, its a design thing (independent of language). This is a big topic, and schools cover it but not deep enough usually. Experience and self study do the rest.

What I was trying to say was some things belong in a class (getters, setters being one of those) and some do not, and learning which is which takes some time (and sometimes the right answer is just how it affects the rest of the design and downstream usage, in less than obvious ways). So yes, put them in the class, not because its easier, but because its correct in this case, and you will over time begin to see when something goes outside a class.
Last edited on
To explain why a method would be better, I will start by explaining the differences between a method and a function from a programmer's perspective.

1.) Functions are defined in the global namespace and not in a class. As long as they are not marked static, they can be accessed from any file as long that file is made aware of them. Functions only have access to the arguments you pass into their parameters, and then possibly global, static, or local variables in their lexical scope. They CANNOT access objects or data that is defined within the scope of another function or a scope that is inaccessible to them without being explicitly passed that data as a parameter (a scope is the region between the function's curly braces: {.....} ).


2.) Methods are almost like functions, except for a few things. First, they are defined within the scope of a class. Many beginners believe that is where the differences end and methods can be used as a normal function is used. They falsely believe that a method of a class is basically a global function within the class. But there is an important difference.

Whenever you call a method in C++, you pass a hidden parameter that is not part of the explicitly stated parameters. This hidden parameter is a pointer to the class object that called it, and it is called this. When you dereference the this pointer, you will receive the object that called the method in the first place. For example, the this pointer of the method foo will contain the address of the MyObject instance and thus it will be able to access its data members. Note that this is passed implicitly even though foo is a nullary method (has no explicit parameters).

MyObject.foo()

Whenever a data member, lets say d1 is accessed inside the scope of foo, the data member accessed is of the object pointed to by the this pointer. You could also explicitly access the d1 data member by using this->d1, but it is not necessary unless using it for disambiguation purposes because the compiler will do this for you in methods automatically when simply referring to d1.

Now, coming back to your question. Why should getInfo() be a method rather than a simple function? See the difference between this code and you will see:

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
#include <iostream>
class Personal
{
    public:
        void getInfo();
        int getVar() {return TestVar;}
    private:
        const int TestVar = 7;
};
    
void Personal::getInfo()
{
    //Code can access the data members directly, without using "setters" because of the "this" pointer:
    std::cout << "Method: TestVar is " << TestVar << "\n";
    //This is the same thing as:
    std::cout << "Method: TestVar is also " << this->TestVar << "\n";
        
}


void getInfo(Personal& my_info)
{
    //Code accesses through setter methods and getter methods of my_info
    std::cout << "Function: TestVar is " << my_info.getVar() << "\n";
    //There is no "this" pointer, so cannot access private member TestVar directly!
    
    //std::cout << "Function: TestVar is " << this->TestVar << "\n";   //ERROR!
}

int main() 
{
    Personal James_Doe;
    //Which syntax do you think is cleaner and makes more sense for Mr. Doe?
    
    //This?
    James_Doe.getInfo();
    
    //Or This?
    getInfo(James_Doe);
    
    //Having getInfo as a method of the class makes more sense because you are accessing Mr. James Doe's information, which is stored in the class. 
    //This is much cleaner than having a function outside of the class take a reference to a Method::Personal object when the method itself stores
    //the object in a "this" pointer. Plus, you can access the data members directly without having to use setter methods. Cleaner implementation.
    //
    //Summary of why it should be a method:
    //  Syntactical Advantage: 
    //                         * Accessing it is cleaner, you are accessing the getInfo method of James Doe's personal record, which should be located in the class
    //                         * No need to pass in the object
    //                         * Can access private data members implicitly using the "this" pointer without setters and getters.
    //                         * If getInfo() is a method, you can get rid of all the setter methods and use this method exclusively.
    //                           You will reduce the size of your class because there would be no need to change a record outside of
    //                           this method (unless you need the setters for some reason)
    //  Logical Advantage:   
    //                         * It makes more sense to be able to "get info" from within James Doe's class rather than outside of it.


Also, you should think of objects of a class as individual, seperate instances. You use "Personal info" which creates a single instance named "info." A better way to think of it is that every object of class Personal is the record of a person, such as John Doe. Each object can thus be a single record of a person in your Personal Information database.
Last edited on
@TheToaster

The term 'method' doesn't exists in c++. It makes no sense to introduce this rather confusing term. Instead use 'member function' like 'member variables'. That makes things easier to understand.
for some reason many books/teachers/etc are using the word method now. I don't think you can stop this bleedover from other languages, its already happened. If we are going to use it, though, I say need a 'madness' term to go with it.
Scott Meyers (in an old Dr Dobb's article):
If you're writing a function that can be implemented as either a member or as a non-friend non-member, you should prefer to implement it as a non-member function. That decision increases class encapsulation. When you think encapsulation, you should think non-member functions. - Scott Meyers in Dr. Dobb's

Some more information:
https://embeddedartistry.com/blog/2017/2/27/how-non-member-functions-improve-encapsulation
https://stackoverflow.com/questions/5989734/effective-c-item-23-prefer-non-member-non-friend-functions-to-member-functions
coder777 wrote:
The term 'method' doesn't exists in c++. It makes no sense to introduce this rather confusing term. Instead use 'member function' like 'member variables'. That makes things easier to understand.

Personal. Subjective. This is just petty quibbling over semantics. I don't subscribe to the religion that some C++ programmers tend to subscribe to that forces them to believe using any terminology that is not used by the C++ standard is a grave mortal sin or believing that using certain language features that are "discouraged" in limited, remote circumstances (such as goto statements) will earn one a place in programming hell. Method is a general OO term. Nearly all OOP languages use it, even those older than C++. I'm not exactly sure how it's "confusing" to use the word method, since many tutorials use the term colloquially:

https://www.w3schools.com/cpp/cpp_class_methods.asp

"...Inside a set of curly braces, the data members (properties) of the class and its methods (behaviors) are declared"

"A class can have a number of members. A member can be a member function (which in turn is a method, constructor, or destructor), a member variable, also called a data member, member enumerations, type aliases, nested classes, and so on"
(Professional C++, 4th Edition, Gregoire).



"Runtime polymorphism is a fundamental concept of object-oriented programming (OOP), typically achieved by late binding of method invocations. ‘‘Method’’ is a common term for a function chosen through runtime polymorphic dispatch. Most OOP languages (e.g. C++ [52], Eiffel [38], Java [6], Simula [11], and Smalltalk [30]) use only a single parameter at runtime to determine the method to be invoked (‘‘single dispatch’’). This is a well-known problem for operations where the choice of a method depends on the types of two or more arguments (‘‘multiple dispatch’’), such as the binary method problem [15]."

(Design and evaluation of C++ open multi-methods by Peter Pirkelbauer, Yuriy Solodkyy, and Bjarne Stroustrup: https://parasol.tamu.edu/~yuriys/papers/OMM10.pdf)
Last edited on
This is the beginners forum and I think we're burying the poor OP in more advanced issues.

At this stage, my advice is "if you you need to pass a function an instance of the class, then make it a method (aka member function)." This gets tricky when you need access to two different class instances. Just use your judgement in that case: maybe it should be a method of one class or of another, or not a method at all. Don't fret over it.

This code is confusing me: void getInfo(Personal&); & void getInfo(Personal& info)

Those are declarations of a function that takes one parameter (an instance of class Personal) and passes it by reference. That means that if getInfo() modifies the parameter instance, it will also change the actual parameter that was passed:
1
2
3
4
5
6
7
8
9
10
void getInfo(Personal &person)
{
    person.setName("Bob");
}
...
int main() {
    Personal p;
    getInfo(p);
    std::cout << p.getName() << '\n';  // outputs "Bob" because getInfo modified p.
}


If you pass a parameter by value then the parameter becomes a copy of the actual argument that was passed into it. Put another way, the parameter is much like a local variable that's initialized as a copy of the argument.

Hope this helps,
Dave
Method is a general OO term. Nearly all OOP languages use it, even those older than C++. I'm not exactly sure how it's "confusing" to use the word method, since many tutorials use the term colloquially:

Indeed, and when I was initially learning C++ in the 90's, the word was commonly used in every textbook I used, for a member function. And as you say, outside of the C++ box, it's widely used when talking about OOP in general. It's also been widely used and understood in every environment where I've written C++ with others, and I don't recall it even once being a source of confusion.

It's useful to be able to distinguish a member function from a free function, and the single word "method" is less clumsy than the phrase "member function", especially if you need to use the term several times in a piece of writing.

I appreciate a bit of pedantry as much as the next software developer, but sneering at someone for using a term that's both useful and widely understood in the field of software development, is just silly.
Last edited on
I get the "method" or "function" discussion, but you will notice if you talk with "C# programmers" who either despise or don't know C++ (or both), you will likely not get away with calling their methods "member functions", and I've had earfuls of supposed differences between the two that never make sense.

That said, as a programmer from that era of the 70's when C itself was new, C++ didn't exist and Pascal was "that other language", I never once heard or read the term "method" until after Java was invented - but, then, I had not heard of Objective-C until after Jobs returned to Apple.

Ok, the whole method versus function thing is a lot more clear to me now. Thanks!

Also thank you for taking the time to explain that to me @TheToaster and @dhayden. This thread has definitely helped me moving forward with functions/methods!

frza45 wrote:
This code is confusing me: void getInfo(Personal&); & void getInfo(Personal& info)


The first is a function declaration, the second is part of a function definition. Look at your original code, line 13 & lines 134 and so on.

There are 3 ways to pass data into a function as a parameter:

1. Passing by value: void getInfo(Personal info) This copies the variable in the function so any changes you make will NOT be a part of the variable from the where the function is called. In your case, the info variable you create in main().

2. Pass by pointer: void getInfo(Personal* info) Using a pointer allows the called function to make changes to the passed variable that will be seen back in main().

3. Pass by reference: void getInfo(Personal& info) Same as using a pointer any changes to the passed variable are seen back in main().

Now, as to the differences between passing by pointer or reference is the syntax of how to call the function. You have your info variable in main(), to call the function that passes by pointer from main() looks like: getInfo(&info);. Using a reference looks like getInfo(info);.

I minimally rewrote your code to add a parameter to pass your info variable in main() using a reference.

So info in main() is the same variable in your function. So any changes in getInfo() are reflected in main after the function call.

Passing by reference means you don't have to make any syntax changes to getInfo()'s code. Passing by pointer requires some changes, though they are easy to do.

When I write a function's declaration that uses parameter(s) I forgo adding a variable name, only the data type, void getInfo(Personal&);, so I know at a glance that line of code is a declaration.

Notice I originally said "The easiest way to fix the problem," not "what would be considered a BETTER way to fix" it.

Others have suggested making the function a member of the class instead of stand-alone as you had it originally. A class method is a better design, though it requires some rewriting of your code.
Topic archived. No new replies allowed.