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.
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");
AFAIK In C++, we call the getter/setter function as 'property'.
The getter/setter is used to get/set a member variable.
One of the advantages of doing this is that we can listen for change, like this:
// In header:
class XXX {
int m_width{};
void OnWidthChanged() {
// do something...
}
public:
int Width() const {
return m_width;
}
void Width(int val)
m_width = val;
this->OnWidthChanged();
}
};
// In CPP:
XXX my_xxx;
my_xxx.Width(123);
cout << my_xxx.Width() << endl;
Now I found static variable can be used to implement similar thing, in a non-OOP fashion I know it cannot handle multiple-instance, so let's just assume XXX is an object that has only 1 instance.
// In header:
int XXX_Width(bool set = false, int val = 0);
void XXX_OnWidthChanged();
// In CPP:
int XXX_Width(bool set, int val) {
static int width = 0;
if (set) {
width = val;
XXX_OnWidthChanged();
}
return width;
}
XXX_Width(true, 123);
cout << XXX_Width() << endl;
My question is, is there a name or term for this kind of functions functions like XXX_Width()?
I'm looking for a name so I can google search for related information.
I'm not asking for name for OnWidthChanged().
Lots of confusion about terminology here.
OOP simply means that you have autonomous classes with their functionality encapsulated. Both your examples use OO, though if they are bad or good design is another matter.
Now I found static variable can be used to implement similar thing, in a non-OOP fashion:
There is nothing non-OOP with your example. It is however probably bad OO design, since multiple instances of your class may access that same function. It is also bad design from a thread-safety perspective.
Sometimes, using static variables locally is perfectly fine though, like for example when implementing "singleton" classes.
In C++, we call the getter/setter function as 'property'
No, that is not a common term. Getter/setter functions are called members, or member functions. Or possibly public member functions, since by definition those must be public. Another term used for them is methods.
The term property is most often used to describe public member variables. Often RAD tools use the term property for such variables.
My question is, is there a name or term for this kind of functions?
A function which is specified by the caller, but called by someone else (the class, the OS, an interrupt etc) is universally called callback function. This is a fairly broad term.
In your case, you seem to use callback functions like "events" - an event is a kind of callback function but a higher level concept. Code like your example could be used for so-called "event-driven design", which is also popular among RAD tools.
The 1st point that should be made is that your "property block" or "getter/setter" are non-conformant. The expected declarations look like:
int Width() const;
void Width(const int);
So when you change the setter to: XXX& Width(int) it becomes clear that you aren't talking about "property blocks" or "getter/setters". So let's talk about what your setter does look like:
It makes a call after width changes. Such a call would typically be an interupt or a signal
It returns a non-const reference to the object. This is the behavior of an operator which notably do have outside class versions
Now let's talk about your function: int XXX_Width(bool set = false, int val = 0) You've set it up with default arguments such that it could behave as either the setter or the getter in your example, notwithstanding the weirdness of your getter's return.
Given the distinction between the 2 options you present, you seem to be asking:
Is there a name for using a functions static variable instead of defining a function and providing getter/setters for a member variable?
A function scoped static variable is called a static local variable.
One word of wisdom on static local variables:
A static local variable is different from a local variable as a static local variable is initialized only once no matter how many times the function in which it resides is called and its value is retained and accessible through many calls to the function in which it is declared [source]
I'm taking a C++ course and I'm stuck on classes and objects. I'm working on an assignment that, in a nutshell, creates a class that takes two variables (let's say length and width).
I've figured out how to do this using get and set functions. But then, we have to use math on these variables. We're supposed to write a function that takes one instance of the class as a parameter (so two variables), and then does math on both this object (the one taken as a parameter) and object that the method of was called.
Part of why I'm confused is the language, and I'm not sure exactly what that means. So far, like I said, I managed to be able to end up with setLength and setWidth variables set via user input. I am really, really stuck on trying to then pass these values (or this object?) to a function and then call the method of another object?
Maybe if someone could help me figure out what "taking an object as a parameter and then doing math on the object i called the method of" means? Or just help with passing objects?
Passing an object works just like passing other kinds of variables. If you were passing an integer into a function, you'd use this syntax for declaring the function:
void myFunction(int myInt);
and if you were passing in an object of class Foo, it would be:
void myOtherFunction(Foo myFoo);
This is sort of like saying, "This the thing I want you to use in your calculations. Copy the object I pass in here!. Passing by reference instead:
void myFunction(int &myInt);
void myOtherFunction(Foo &myFoo);
lets you modify the value you pass. It's also significantly cheaper with larger objects than passing by value which was the original syntax in this answer. You can think of it as you saying to the computer, "I know you want this value, but I'm not going to let you copy this. Just look over there, instead, and you'll find what I want you to work with." But sometimes you don't want to modify the thing you're working with!
Sure, you could be very careful in your function to avoid changing things, but the C++ language lets you say that you shouldn't modify the variable, and then will check that you don't modify it for you!
This can be accomplished by using
void yetAnotherFunction(const Foo &myFoo);
The const is what says "Don't let me be modified!" to the compiler, and the compiler will listen.
Say you want to assign a few values to a simple object, using a (non-member) function:
// a struct should usually hold simple groups of data,
// that don't do much by themselves. Their members are
// also public by default.
struct MySimpleType{
int first;
int second;
};
// object is passed by reference so it can be modified.
void modifier(MySimpleType &object, int newFirst, int newSecond){
object.first = newFirst;
object.second = newSecond;
}
then in your client code (probably a main function, at this point in your coding career) you do this:
MySimpleType object;
modifier(object, 13, 12);
cout << object.first << ", " << object.second;
which should print out:
13, 12
Thinking of pieces of code as "objects" can be difficult a first, but it will likely be one of the most important things you learn (because object oriented programming is widely used in industry and academia). There is quite a lot of background you need in order to use objects effectively in c++, but I'll try give a concise introduction..
Firstly, it's important that you understand the difference between a "class" and an "object." A class is an abstraction that allows you to define an object. If I want to make a Horse object, I use a Horse class to define what is important about a horse. This class might have fields defining its name, owner, hair color etc. However, the Horse class is not a horse. It tells you what it means to be a Horse, but it isn't one. In order to define an "object" of type Horse, we would write the following:
Horse myHorse = new Horse("Sea Biscuit", "Howard", "Black");
Keep in mind that Horse is the class, but Sea Biscuit is the horse itself (the object).
You may be well aware of the above, but it can often be a tough concept to grasp, so I thought I would mention it.
Now, if you want to perform math on some objects, this is relatively straightforward with using member functions. Lets define a new class to do some math on (because horses and math don't mix).
class Wallet
{
int _pennies;
// This is a constructor. It allows us to write: Wallet myWallet(100);
public Wallet(int pennies)
{
_pennies = pennies;
}
public void addPennies(int pennies)
{
_pennies = _pennies + pennies;
}
public void stealPennies(Wallet &stolenWallet)
{
int stolenPennies = stolenWallet._pennies;
stolenWallet._pennies = 0;
this.addPennies(stolenPennies);
}
}
We can now make some objects, and modify the fields in both objects with a single call to stealPennies:
int main()
{
Wallet myWallet(10); // Creates a wallet with 10 cents.
Wallet anotherWallet(50); // Creates another wallet with 50 cents.
myWallet.stealPennies(anotherWallet);
// myWallet now has 60 cents, and anotherWallet has none.
}
Note: The & before the name of the argument in the stealPennies function means it will be passed by reference. Usually when you pass an argument to a function it is passed by value, which means the variable in the function is a copy of the argument you passed. Putting the & before the name of the argument means the variable in the function is the same variable instead of a copy. (This is highly simplified.. it's unlikely that you will be able to fully understand passing by reference until you become familiar with pointers). Also, it is common practice to use some kind of naming convention when defining variables that are part of a class. Putting an underscore before the variable name is common (such as _pennies in this example).
Hopefully this is helpful to you (and hopefully it works, as I can't test it at the moment). I have tried to make the code as readable and explicit as possible.
As from your comment:
" I can't seem to figure out how to "assign" this user input to the object. So in the example above, i have setLength variables taken from user input. I cant figure out how to assign these variables to a new object, so that then the object is passes, the user input ( in the form of variables) is passed along with it!"
What I think you actually need is some function(s) to manipulate your class member variables by reading from a std::istream, and passing the object instance targeted as a reference:
class foo {
public:
foo() : x(12), y(42.0) {}
private:
friend std::istream& operator>>(std::istream& is, foo& subject);
std::istream& getfrominstream (std::istream& is) {
is >> x;
is >> y;
return is;
}
int x;
double y;
};
std::istream& operator>>(std::istream& is, foo& subject) {
return subject.getfrominstream(is);
}
Call like:
int main() {
foo f;
std::cin >> f;
}
I am trying to do this C++ tutorial. I am a beginner in C++ programming. I don't get why they use setValue and getValue in class Class1 and not setClass1. In the other tutorial they use setA and getA in the class class Class1. Here are the codes:
class Class1 {
int i;
public:
void setValue( int value ) { i = value; }
int getValue() { return i; }
};
the second code is:
class A{
int ia;
public:// accessor method because they are used to access a private date member
void setA ( const int a);
int getA ()const;
int getA ();
};
Please help...
The names are arbitrary, you can use any function names you wish (subject to language rules, of course).
However, although you can use xyzzy() and plugh() as getter and setter, it's not really a good idea.
You should use something that indicates the intent of the call, such as getTemperature() or setVelocity(). And these don't even have to map one-to-one to internal fields since encapsulation means the internal details should not be exposed.
By that, I mean you may have a getTemperatureC() for returning the temperature in Celsius even though the internal field is stored as Kelvins:
double getTemperatureC(void) { return kelvins - 273.15; }
void setTemperatureC(double t) { kelvins = t + 273.15; }
(or a getter/setter may use arbitrarily complex calculations).
Using getA() for a class A may well cause you trouble when you create class B to inherit from A but this is outside the scope of the language. But it's good programming practice to follow the guideline above (functions should indicate intent rather than internals).
I was confused on why they use the same name in get and set with the class name, and different get and set name on the other class. Will the set and get names affect the code?
The answer is No.
getter and setter are usually called accessor and mutators in a class. They are just member functions named according to some convention, easy for people who read the code to understand the purpose of those functions, so it is like common sense to name those member function starting with get if you try to access the member variables and starting with set if you try to change some member variables. The names can be any valid identifier.
So setValue or setA are just identifiers for those member functions. It will not affect the code.
Meanwhile, different class can have the same named getter or setters since those function names are in different class scope.
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.