I'm a CS student and right now we're learning about inheritance. For our assignments, the teacher gives us a main.cpp file and a class header. We're expected to create a .cpp implementation of the header without altering the given files. I've done most of it, but here's what I can't implement:
// File: employee.h
class Employee : public Person
{
private:
static Company company;
public:
static Company GetCompany();
static void SetCompany(const Company& company);
}
It's the [static void SetCompany] that I'm unable to work with. Normally in the implementation I'd just do
// File: employee.cpp
void Employee::SetCompany(const Company& company) { this->company = company; }
but I get the error "'this' may only be used inside a nonstatic member function". I'm not really sure how else I'm supposed to assign the variable, and it was never addressed in class. Any help would be appreciated. Just note that this is pretty much the format I'm expected to keep, so hopefully any advice won't stray too much. Anyway, thanks in advance and let me know if anything needs to be clarified... or if I'm just being blind and/or stupid about this.
To access a static field, use Employee::company, as you cant use this because it is meant to refer to an instance of a class.
Your setter will become
void Employee::SetCompany(const Company& company) {
Employee::company = company;
}
But if you try to simply replace your setter, your compiler will throw an error, saying that it doesn't know Employee::company. Because it is not instantiate. You need, in your .cpp file, as you would do with a function to declare your field with
Company Employee::company;
To expand on the earlier comment, you can refer to static members with their full name, for example Employee::company. So, you should be able to fix your example by simply changing the function to this :
static void SetCompany(const Company& company) { Employee::company = company; }
This is because static member variables are independent of a particular instance of the class. The this keyword refers to the specific instance of the class. So, by changing a static member, all instantiations of the class have this change.
For static variables, you just refer to the class variable and not an instance.
void Employee::SetCompany(const Company& company) {
Employee::company = company;
}
I think it's important for you to understand the compiler's and language scoping rules. When a method (static or otherwise) has a PARAMETER that has a name "company", but the class has an accessible MEMBER (static or otherwise) that has a name "company", what are the rules for resolving the bare name "company"? What if there was no parameter named company, how can/should you reference the member?
Here's another wrinkle - what if there is a LOCAL parameter named company?
void Employee::CompareCompany(const Company &company)
{
Company company("another company");
// which company is being referenced on the LHS (left hand side)
// of the == expression below? The method parameter or the local variable?
if (company == Employee::company)
stout << "They match!"
}
Do you think this is a good idea for me to keep using the same name? They're all instances of Company, so why isn't "company" a good name for all of them???
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");
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 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.