I was just wondering if you could explain to me how functions with parameters work.
I've been following tutorials etc but they do not seem to explain how the code works to get the output. Heres an example:
#include <iostream>
using std::endl;
using std::cout;
using std::cin;
using std::string;
class stan
{
public:
void setName(string x)
{
name = x;
}
string getName()
{
return name;
}
private:
string name;
};
int main()
{
stan con;
con.setName("Bruce Almighty");
cout << con.getName() << endl;
}
I do not get how we get from the public string name to the private string name. What I'm saying must sound really confusing but I don't know how else to put it, I would just like to be able to understand how this code works.
Thanks to anyone that helps, it means alot
Program starts at function main.
It declares a local variable con of type stan.
Method setName of object con is called with argument "Bruce Almighty".
Method with heading void setName(string x) starts executing. Parameter x takes the value of the corresponding argument ("Bruce Almighty").
Private member name of this object is set to the value of parameter x ("Bruce Almighty").
Method setName returns to the point it was invoked.
cout represents console output.
To apply operator <<, con.getName() needs to be evaluated. Method getName of object con is called with no arguments.
Method with heading string getName() starts executing. No parameters involved.
Value of private member name of this object is returned ("Bruce Almighty").
Method getName returns to the point it was invoked with value "Bruce Almighty".
cout uses this value and produces it in the console.
The same cout object produces endl value in the console. endl make a new line to be created in the console.
http://www.cplusplus.com/doc/tutorial/classes/
private members of a class are accessible only from within other
members of the same class or from their friends.
protected members are accessible from members of their same class and from their friends,
but also from members of their derived classes.
Finally, public members are accessible from anywhere where the object is visible.
Basically, a private member is something that ONLY a class function can access. So "string name" can only be read/write from class functions. Public functions/variables can be called from outside the class, the example you gave is "setName" and "getName"
So in order to write or read the private string, your code uses the public functions you created.
Basic steps:
con.setName("Bruce Almighty");
calls the setname function and passes the string "Bruce Almighty" to it.
void setName(string x)
receives the string "Bruce Almighty" that you sent, and calls it x.
name = x;
assigns the value of x, which is "Bruce Almighty", to the variable name.
con.getName()
asks for a value from the getName function.
string getName()
declares the getName function as one that returns a string.
return name;
takes the string held in the variable name, which setName set to "Bruce Almighty" and returns it to the caller, which sends it to cout for outputting.
setName is somebody who helps you to deliver your string, "Bruce Almighty" to the private name field in the stan village.
You are saying, "Hey setName, I am going to pass "Bruce Almighty" argument as your parameter x. I don't care how you do it, but simply deliver it to the private name field!
setName says, "Ok, I got it, you mean my x parameter is Bruce Almighty right?"
You say, "Yes right!"
setName says. "Ok, I am done. You don't need to know how I did it. This is what we call abstraction. You simply order, but you don't need to understand how I did it. However, just in case you want to know, I did it by using the assignment operator =. I placed the private name field on the left side, and my parameter x on the right side. Because you provided Bruce Almighty to my parameter x, it is assigned to the private name field. Boom!"
Inside a class definition you can access data members using just their name. E.g. inside setName body the names of all members are in scope, thus also the private data member name. In this way the statement:
name = x;
assigns the value of x (the argument of setName) to name, which is the private data member.
You must be careful when naming members, though, as name clashes may arise if a local variable is named the same as a member. You can avoid them either prefixing your members with this-> like:
this->name = x;
or using a naming convention such as giving to any data member's name a prefix:
m_name = x; // "m_" stands for "member"
...
private:
string m_name;
this is a C++ keyword representing a pointer to the object on which you invoke your methods (i.e. member functions). It can be used to refer to that object inside a class definition. Thus this->name means "the member called name inside the object pointed by the pointer this"
Related
Disclaimer: I'm fairly new to programming and my terminology may be way off. When I say "class pointer name", I mean the "A" in "myClass A" and in "A.Fill(...)".
I'm not sure how to formulate my question to make it as clear as possible, but let me try:
class myClass{
public:
// stuff
Fill(string msg)
{
// does stuff
cout << msg + "some extra text"; /*here I want to somehow get the name of the class pointer
which was used when calling this method, rather than having to manually pass it on as a string.*/
// more stuff
}
};
int main()
{
myClass A;
myClass B;
myClass C;
A.Fill("A");
B.Fill("B");
C.Fill("C");
}
This code is currently doing exactly what I want. However, I am wondering if it's possible to somehow get the class pointer name from within the method, rather than having to manually pass on a string argument every time?
I know that in macros I can use #A #B #C to get exactly that, but I'm uncertain how this would be applied for my code, and if it's possible at all.
You don’t want variable names, and you don’t want to be passing them in each time you call a method of the object.
You want object names. You need to give the A object a name, and then this name can be used by all of its methods.
Then, if you want convenience, instead of instantiating it as ClassA A("A");, you can have a macro that does it, like
#define ClassA_instance(var) ClassA var(#var)
Use:
ClassA_instance(A);
This way, you create an instance of that class that has the same name as the variable - but that’s pure convenience. You will find, soon enough, that you can give objects better names than what suffices for a variable name, especially if those objects are stored inside of other objects, where member variable names may be unwieldy due to eg. the m_ prefix. You can then also combine object names, so that object B inside of some object A will have its name set to “A.B” or similar. Tying the name to the name of a variable will have very limited uses.
ClassA has to store its name of course, and its constructor must accept the name. Eg.:
ClassA {
std::string m_objectName;
public:
ClassA(const std::string &name) : m_name(name) {}
ClassA(const char *name) : m_name(name) {}
...
};
You could factor out the naming aspect into a base class, although there’s so little code to it that I don’t see the sense in doing it - not unless you have other, better reasons to have a common base class.
Not even the compiler knows what variable name was used to call a member function. But you're right, you can use a macro to do what you want.
#define FILL(X) X.Fill(#X)
FILL(A);
FILL(B);
FILL(C);
No, there isn't a way to get a variable name automatically from with a class's function.
To do what you're asking for, it would have to be passed in.
Fill(string name, string msg)
{
//...
}
Perhaps you could come up with a macro that could be used in places where the function call is made that would streamline passing in the name.
myClass A;
CALLFUNCTIONANDPASSNAME(A, Fill("A"));
But in my option that just adds complexity for little value.
Furthermore there are lots of situation where trying to determine the variable name is going to be surprising or unhelpful. For instance:
myClass* p = new myClass[2];
p->Fill("...");
++p;
p->Fill("...");
Here Fill is called on two different instances, but the name of both would be "p". (Disregard the fact that this example does not show good memory management practices. I'm keeping it simple to only show what's relevant to this question.)
The better recommendation for class instances to have a name is to treat that as any other data you want a class to have - carry it in a member variable.
class myClass
{
string Name;
public:
myClass(string name)
{
Name = name;
}
void DoSomething()
{
cout << "My name is " << Name;
}
}
And then construct your instances with the desired name.
myClass fred("Fred");
Say there is a class:
class person {
int age;
string name;
public:
person(int age,string name)
:age(age),name(name)
{}
};
I have the following questions:
Can the constructor initializer(with the ":" syntax) be used somehow outside of classes?Is it just for classes?
A variable declaration such as int x(2) works for obvious reasons.x is an object with value of 2.But age(age),how does that work?Is the syntax made that way to make initialization easier?
Based on that,how come can the parameter age & member age have the same name and not confuse the compiler?Member age is in scope(as a private member),but parameter age is also in scope.When this happens with ordinary functions,the "localest" is the one that prevails.
Thanks!
It doesn't 'confuse' the compiler. Since it's a member initializer list it's scope is the same as constructor. Therefore function scope wins over class scope. And therefore the member age is initialized with the paramter age.
Normally I would not use the same name (even though certainly possible) as it's both brittle and somewhat unclear. For example:
struct Decision {
bool launch_nukes;
Decision(bool /*launch_nukes*/) : launch_nukes(launch_nukes) {
}
};
At best will only give a warning.
Can the constructor initializer(with the ":" syntax) be used somehow outside of classes?Is it just for classes?
Member initializer lists can only be used by constructors only.
A variable declaration such as int x(2) works for obvious reasons.x is an object with value of 2. But age(age), how does that work? Is the syntax made that way to make initialization easier?
Based on that,how come can the parameter age & member age have the same name and not confuse the compiler? Member age is in scope, but parameter age is also in scope. When this happens with ordinary functions, the "localest" is the one that prevails.
we have and expect member(init), so for member, only members of the class are seen (and Base class or own class for delegating constructor). We can say that we are only in the scope of the class.
For init, indeed regular scope applies, and parameters age/name hides members with same name.
We just started talking about classes in my intro to CS class and I am a bit lost on how to know when a variable is private or not. We had a lab today and this is what the .h file contained:
(the class containing the below code is called personType)
class PersonType {
public:
void print() const;
//Function to output the first name and last name
//in the form firstName lastName.
void setName(string first, string middle, string last);
//Function to set firstName and lastName according
//to the parameters.
//Postcondition: firstName = first; lastName = last
string getMiddleName() const;
//function to return the middle name
//Postcondition: the value of middlename is returned.
string getFirstName() const;
//Function to return the first name.
//Postcondition: The value of firstName is returned.
string getLastName() const;
//Function to return the last name.
//Postcondition: The value of lastName is returned.
personType(string first = "", string middle = "", string last = "");
//Constructor
//Sets firstName and lastName according to the parameters.
//The default values of the parameters are null strings.
//Postcondition: firstName = first; lastName = last
private:
string firstName; //variable to store the first name
string middleName; //variable to store middle name
string lastName; //variable to store the last name
};
In int main, I declared an instance of the class called personType myself;
would the object myself have access to these private variables because it is apart of the same class containing the private variables? In what scenario would I not be able to access these private variables?
A member that is private can be accessed (without any or on any instance of the class) from within code written inside the class definition and all out-of-class definitions for members of the class.
That means in particular that where ever you implement PersonType's methods, they can access the private members in their body.
Any other code cannot access the private members by default (without a friend declaration).
In particular if you create an object PersonType person; in main you cannot use person.firstName. You can do the same in the implementation of PersonType::setName though and you also can use the implicit instance's firstName in PersonType::setName's implementation.
Accessibility is not specific to certain instances of classes. It is only a matter of the context in the code that the member names are used in. It doesn't matter whether the member is referred to as firstName, person.firstName, this->firstName, or any other way. In a member function, it also doesn't matter whether person is the current instance or some other instance of the class.
Each time the compiler encounters a name in your code it figures out to what declaration this name refers to. The accessibility check then looks at the context in which the name appeared and compares that to the result of the name-lookup to figure out whether the access should be allowed according to the rules above.
any method that belongs to PersonType will have access to the private variables, for instance string PersonType::getLastName() const
any other code, including main(), will not be able to access these variable.
void main()
{
PersonType myself;
myself.getLastName(); // OK!
std::cout << myself.lastName; // ERROR! lastName is private
}
Well, to know if it's private or not, you just have to check if it's in a private section of the class declaration :-)
But, expanding on that, an object (like myself) will always have access to its private members (and private members of other objects of that class, assuming it can see the actual object itself). Privates are generally(a) meant to prevent things outside the class from accessing them directly.
This prevention includes, for example, trying to do things like myself.firstName = "Pax" from your main function.
The usual way to get that level of access from outside is to provide getters and/or setters in the class. Using these allows you to do things like:
catch invalid attempts to change the variables; or
hide the internals of the class so that they can be changed without affecting the interface.
That is what those get* and set* methods in the code you posted are for, although I would have personally returned constant references for the getters - there's little point in copying something that may only be read:
const string &PersonType::getFirstName() const { return firstName; }
const string &name = pt.getFirstName(); // to just use it as is.
string name = pt.getFirstName(); // to get a modifiable copy.
(a) Things tagged as friend can bypass this protection but I won't cover that here, it would unnecessarily complicate the answer. You may also want to look into protected at some point, this allows sub-classes to access members (private members are off-limits to sub-classes) while still protecting them from things outside the inheritance hierarchy.
Each instance of personType has access to its own copies of the private variables of the class. It also has access to the private variables of other instances of the same type.
Non-personType variables and functions will not be able to see those variables. That includes variables of the type of any class you might derive from personType.
would the object myself have access to these private variables because it is apart of the same class containing the private variables?
This comes from a perspective that sees objects as having access to things. For some meanings of "access", this perspective can be useful. However, when the meaning of "access" involves access specifiers (public, protected, and private), it is more useful to view code as having access, rather than objects.
Code implementing a class has access to the private details of that class. Other code does not. In particular, the code in your main function has no access to any private details of any class.
(The friend keyword can change things, but it should not. If something declared a friend cannot reasonably be considered part of the implementation, then it likely has no business being a friend.)
would the object myself have access to these private variables because it is apart of the same class containing the private variables?
Yes. Each instance gets its own copy of the variables (unless you declare them static, but that's probably a topic for another time). So, if you have an object:
PersonType person;
There is conceivably these variables:
person.firstName
person.middleName
person.lastName
And, just to cover all my bases, these are available inside the class. So take the following function:
string getMiddleName() const;
The implementation of this function will have access to all private variables. So, for instance:
string PersonType::getMiddleName() const {
return middleName; // if this is called from person (that is, person.getMiddleName())
// then "middleName" here is person.middleName
}
Here, person.getMiddleName() can access person.middleName.
In what scenario would I not be able to access these private variables?
Most every other scenario where a function is not a part of the class PersonType. However, I will give some examples for the sake of clarity.
int main() {
PersonType person;
// bad
person.middleName;
return 0;
}
Here, you can't access person.middleName because main() isn't a part of PersonType. It is main(), i. e. another function. A general rule of thumb is if it is not part of the class, you can't access private variable.
void function(PersonType person) {
person.middleName; // still can't do it
}
Here, function() is not part of PersonType, so it doesn't have access to middleName.
There is only one exception to this rule about not being able to access private variables outside the class, and that is friend functions. To create a friend function, you have to modify your header a bit:
class PersonType {
public:
friend void friendFunction(PersonType person);
//...
};
Now, friendFunction() can access private data members:
void friendFunction(PersonType person) {
person.middleName; // it's fine. We're friends
}
The most common use of friend functions is with a slightly advanced topic called "operator overloading", which your class will almost certainly go over eventually.
Anyway, in the mean time, think of it this way: Is it part of the class? It can access private members. Is it a friend of the class? It can also access private members. Is it anybody else? No, it can't access private data members.
I'm watching C++ tutorials on youtube, and I'm on a video titled Using Variables In Classes. In the video he explains that if we were to make variables public in classes, that it's bad programming. It'll work, but it's still bad programming. The program he wrote out consisted of a class with a private variable, and he used two functions to access the variable. Code looks like this:
#include <iostream>
#include <string>
using namespace std;
class MyClass {
public:
void setName(string x)
{
name = x;
}
string getName()
{
return name;
}
private:
string name;
};
int main()
{
MyClass TO;
TO.setName("Taylor");
cout << TO.getName();
}
My question is, why did we have to create a separate function to return name, instead of returning it in the first function? In my code, I returned name in the first function and it went well.
There might be cases when you want to set the variable, perform some other operations and then print the variable, hence the two functions.
If you just want to input the variable and print it, one function is enough.
Member functions that are prefixed with set are called setters, and member functions that are prefixed with get are called getters.
They can have other names too, of course, but those are the common naming conventions. The main idea is that
getters "get" (return) a variable from inside a class, while
setters "set" (change) a variable inside a class to some specific value.
For the rationale behind the use of getters and setters, see the answers here. They cover a lot of good points on why getters and setters are a good thing in object-oriented programming.
Declare variables are private and use public functions are interface to set and get variables is a best practice. Why is not returning value from set function is an implication of 'separation of concern rule'. Please read this to get more info about it http://en.wikipedia.org/wiki/Separation_of_concerns
Because otherwise you wouldn't be able to write code to get the name if you don't happen to also be setting the name.
Consider trying to write a function to print the name of a MyClass passed as a parameter:
void printName(MyClass my_class){
std::cout << my_class.getName() << "\n";
}
How would you write this with a setName function but no getName function?
In your trivial example you don't need getName but you don't actually need MyClass either. You could just write:
std::cout << "Taylor\n";
but clearly that is not the point of the tutorial.
I have a lib.h, lib.cpp and test.cpp. I would like to ask what is better?
lib.h
class c
{
std::string name;
}*cc;
lib.cpp
{
std::cout << "the name is:" << name << std:: endl;
}
test.cpp
main()
{
c tst;
tst.name="diana";
}
What should I use? std::string name or std::string *name? How can i work with &name, how will my code change and which one of these 2 methods is the best one?
First, I hardly believe your code will compile while in your main you try to get access to private data member name.
About &. It is really hard to define where to start. In short std::string &name is called reference to object of type std::string. Reference is somehow an alias to some other object. The main feature is, that you always have to initialize refence to object while creating and you can't reinitialize reference to point to another object. More about this feature you can read in C++ FAQ
EDIT
Generally you can declare public, protected and private members of your class in with arbitrary ordering:
class MyClass {
//here goes private members when working with class
//and public when working with structs
public:
//here goes public members
protected:
//here goes protected
private:
//here goes private
public:
//here goes public again
};
Ordering of members declaration is actually code policy question. For example, google style guide recommends to put all public members before private.
About hiding function members (not necessary private). You actually can't hide function member declaration, but there are several ways to "hide" implementation, but I am not sure that it's the definition of hiding you are talking about. But you can check PImpl idiom. This requires understanding of pointers so I advice you to start with them first.
Small code sample for working with pointer to string:
#include <iostream>
#include <string>
class MyClass {
public:
std::string *pstr;
};
int main() {
std::string str("test");
MyClass myObj;
myObj.pstr = &str;
std::cout << myObj.pstr->c_str() << std::endl;
}
std::string & name; is a reference. You'll need to initialize it in the constructor, so it actually refers to something. What it refers to must exist as long as your c instance exists. It's not the right solution for this.
std::string name; is an actual variable, use this.
std::string &name is "only" a reference to a string (a bit like a pointer). Because the name definitely belongs to the class c, I think it would make sense to have an instance there.
References are put to good use when passing instances around (to avoid copying).
const std::string&
is reference to a std::string, it is very important to understand the implications of that with respect to the lifetime of variables. Once the referenced variable goes away, the reference is no longer valid, and this is a very common way to f*ck up for beginning C++ programmers.
YMMV, Pick up a good tutorial first, and meanwhile, don't use references unless you know why and what you're doing
Good luck
I'd use: string name; because string* name is just a pointer that needs to be given a value, and then I'd have to think of a way to clean it up later all by myself, and string& name, would be just a name that again has to be initialized.