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;
}
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");
I have a class which has a std::function as a member variable.
class Animal
{
public:
Animal(const std::function<double(const int x)> MakeNoise) : MakeNoise(MakeNoise) {}
void Print(const int x) { std::cout << this->MakeNoise(x) << std::endl; }
private:
const std::function<double(const int x)> MakeNoise;
int a = 4;
int b = 8;
int c = 12;
};
I would like to be able to swap out the MakeNoise function without subclassing Animal by passing various lambdas.
const auto MakeNoise1 = [this](const int x)
{
return a + b + x;
}
const auto MakeNoise2 = [this](const int x)
{
return a + b + c + x;
}
Is it possible to capture this if the definition of the function is in a different file?
Is it possible to use [&] (capture by reference) to capture x pass into Print ?
Lastly, is there a better way to define this class so I can swap the function in and out?
If I add this the compiler says error: invalid use of ‘this’ at top level which makes sense since the definition of the lambda is not within a class.
I do not think this is possible to do directly. After all, the lambdas as given don't know anything about Animal. You can work around it by having the function's signature be
(const Animal& animal, const int x) instead and accessing it through animal.
this is a special name inside member functions. If MakeNoise1 wants to capture this, it needs to be in a member of Animal. Your compiler told you so, and you interpreted that message corerctly.
That's not a big restriction, since Animal::a is private anyway.
You can define Animal methods in other .cpp files, but you'd still need to declare these methods in class Animal, so this might or might not match your larger design.
If you are defining the lambda outside a member function, then no, you cannot capture this because there is no this to capture. A capture is a way to provide access to variables that are defined at the point where the lambda is defined. A capture cannot capture things that do not exist at the point of capturing.
What you want to do is provide access to variables that are defined at the point where the lambda is invoked. This is the job of parameters, as in this->MakeNoise(this, x) or perhaps MakeNoise(*this, x). (Your Print wrapper can easily provide the extra parameter. In fact, adding parameters is a common motivation for writing wrapper functions.) However, I suspect that this might not be the best approach.
Instead of thinking about how to access this, think about what MakeNoise is supposed to do and what it needs to do that. Does it really need the entire Animal including private data? If so, it probably should be a member function. Bite the bullet and create a plethora of derived classes (and provide protected access to the data). Does it instead need the entire Animal, but only the public interface? If so, a lambda that takes both const Animal & and const int as parameters might be reasonable. Furthermore, it might be reasonable to expand the public interface to accommodate this.
Perhaps, though, you are in the case where MakeNoise does not really need an Animal so much as a few key bits of data. This is the point where you have to look at your design and your levels of abstraction. We cannot do this for you because, as is appropriate for a StackOverflow question, we do not have the complete picture. However, I can present for consideration the possibility that things other than animals can make a noise. Are your MakeNoise lambdas supposed to be abstract enough to not care what is making the noise? If so, you might consider adding specific data as parameters to your lambdas. Your Print function would become something more like the following.
void Print(const int x) { std::cout << MakeNoise(x, a, b, c) << std::endl; }
I am assuming that Animal has been (appropriately) simplified for this question, and that an Animal object really has a lot more data than a, b, and c. If this assumption is false, you are in the case of needing an entire Animal. However, if the parameters you would need to pass to MakeNoise are few in comparison to the data in Animal, this might be a better semantic fit to your design. Might. It all comes back to making design choices that are sensible and consistent. Think abstractly while avoiding over-engineering. Keep in mind that you need to provide the same parameters to each lambda (but the various lambdas can have different captures).
Here is an example lambda that could be used for this last approach, assuming the type of MakeNoise – both of the data member and of the parameter to the constructor – has been updated.
int main()
{
Animal cheetah{ [](int x, int a, int b, int c) -> double
{
return a + b + c + x;
}
};
cheetah.Print(2);
}
If you really want to use const int instead of int, you could. To me, it seems unnecessarily restrictive for a non-reference, but that's more style than substance.
Thanks in advance for the replies.
store() is a function of Backpack class which is holding an array of pointers (Item * items). The arguments sent to store() are correct (tested by printing them out with cout). displayInventory() still prints the previous Item object's members at the end of the function.
void store(string & name, float weight, int power, int slot)
{
items[slot] = new Weapon(name, weight, power); // Weapon is a derived class of Item
this->displayInventory();
}
Thanks.
EDIT: Researching vectors now.
First, here are a couple of things which might ease your life (and the life of those who will read your code). It would simplify your code. Hence it will make easier to understand and debug:
Use relevant names for your variables.
Example:
void store(string & name, float weight, int power, int slot)
{
items[slot] = new Weapon(name, weight, power);
numItems+=1;
this->getInventory();
}
Use relevant / consistent names for your methods.
Here, it's hard to understand what is the purpose of getInventory() because it starts with get, yet its return type isvoid. (Maybe you meant buildInventory()?)
You don't need to redefine in your derive class, what is already in the base class.
In particular you don't need to redefine name, weight and power (and their getters) in Weapon, since it's already defined in Item
If you don't define any constructor in a class, the compiler will provide a default one without arguments.
It means you can remove the line Container(){;}
Don't reinvent the wheel. You'd better use a std::vector rather than trying to handling yourself pointers and arrays.
I'm pretty sure this last advice can by itself fix your issue. In particular, if you use a vector<Item>, you won't need to manipulate pointers yourself anymore. It means no more new and no more delete.
I'm trying to learn C++, Thanks to this article I find many similarity between C++ and Python and Javascript: http://www.cse.msu.edu/~cse231/python2Cpp.html
But I can't understand C++ Classes at all, they looks like Javascript prototypes, but not that easy.
For example:
//CLxLogMessage defined in header
class myLOG: public CLxLogMessage{
public:
virtual const char * GetFormat (){
return "Wavefront Object";
}
void Error (const std::string &msg){
CLxLogMessage::Error (msg.c_str ());
}
void Info (const std::string &msg){
CLxLogMessage::Info (msg.c_str ());
}
private:
std::string authoringTool;
};
Question: What is this Public/Private stuff at all!?
Edit: To be honest, I more enjoy C++ than Python, because I can learn truth meaning of everything, not simple automated commands, for example I preferred to use "int X" rather than "X" alone.
Thanks
myLOG is the name of the class. It inherits (look it up2) from CLxLogMessage and has the functions GetFormat (which is virtual and can be overridden by subclasses and called through base class pointers, look it up2), Error, and Info. It has the data member authoringTool which is a string.
The public and private stuff is access specifiers. Something in the private section can only be used by the class's member functions, and stuff in the public section can be used by anybody. There is another type of section called protected which means that only a class and its subclasses can access it, but nobody else1.
If you start adding stuff to a class without setting an access level first, it defaults to private.
You can have as many public, private, and protected sections as you want, in any order.
You need these different protection levels because you don't want other people messing with your data when you don't know about it. For example, if you had a class representing fractions, you wouldn't want someone to change the denominator to a 0 right under your nose. They'd have to go through a setter function which would check that the new value was valid before setting the denominator to it. That's just a trivial example though. The fact that Python does not have these is a shortcoming in the language's design.
All your questions would be answered if you had read a C++ book. There is no easy way out with C++. If you try to take one, you'll end up being a horrible C++ programmer.
1 You can let somebody else access private and protected members by declaring them as friends (look it up2).
2 Sorry for saying "look it up" so much, but it's too much information for me to put here. You'll have to find a good resource for these kinds of things.
Even though there's no way to give a comprehensive answer or anything near that, maybe think about it like this: classes are types. Consider this:
int n;
Here "int" is the name of a type, and "x" is a variable of type "int". There are basic types in C++, like "int", "char", "double". Now we can also make new, compound types from old types:
struct Foo
{
int n;
char c;
double d;
};
This defines a new type called "Foo", and Foo x; makes a new variable of that type. Now we can add some magic to the type "Foo":
class Foo
{
int n;
double d;
public:
Foo() : n(20), d(0.5) { } // "constructor"
};
The keywords struct and class almost mean the same thing, so we still have a compound type that has two member variables, n and d. However, this type also has a member function, and this one gets called every time you create a new Foo object. So when you say, Foo x;, then this variable's member value x.n will be set to 20 and x.d will be set to 0.5.
So that's that in a nutshell: Classes are types with built-in magic. And you are the magician.
The private and public is to do with data encapsulation, it means you can change the implementation of the class without affecting how it is used. I suggest reading up on some of the theory of object orientation.
Before I was trying to map my classes and namespaces, by using static calls I succeded and now I need to map the functions of my classes because they will be used dynamically.
Firstly I was thinking to hardcode in the constructor so I can assign a std:map with the string of the name of function pointing to the function itself.
for example:
class A{
int B(){
return 1;
}
};
int main(){
A *a = new A();
vector<string, int (*)()> vec;
vector["A.B"] = a.B;
}
By that I have mapped the function B on A class, I know that I only mapped the function the instance and thats B is not static to be globally mapped.
But thats what I need, at somepoint someone will give me a string and I must call the right function of an instance of a class.
My question is if I only can do that by hardcoding at the constructor, since this is a instance scope we are talking or if there is somehow a way to do this in the declaration of the function, like here for namespaces and classes:
Somehow register my classes in a list
If I understand you correctly, you want your map to store a pointer that can be used to call a member function on an instance, the value being chosen from the map at run time. I'm going to assume that this is the right thing to do, and that there isn't a simpler way to solve the same problem. Quite often when you end up in strange C++ backwaters it's a sign that you need to look again at the problem you think you have, and see whether this is the only way to solve it.
The problem with using an ordinary function pointer is that a non-static member function is not an ordinary function. Suppose you could point to a member function with an ordinary function pointer, what would happen when you dereferenced that pointer and called the function? The member function needs an object to operate on, and the syntax doesn't provide a way to pass this object in.
You need a pointer to member, which is a slightly obscure feature with relatively tricky syntax. While an ordinary pointer abstracts an object, a pointer to member abstracts a member on a class; the pointer specifies which class member should be called, but not which object to obtain the member from (that will be specified when the pointer is used). We can use it something like this:
class B;
class A
{
B some_function()
{ /* ... */ }
};
B (A::* myval)() = A::some_function;
Here myval is a variable that indicates one of the members of class A, in this case the member some_function (though it could point to any other member of A of the same type). We can pass myval round wherever we want (e.g. storing it in an STL container, as in your example) and then when we want to call the function, we specify the instance it should be called on in order to locate the function:
A some_a;
B newly_created_b = (some_a.*myval)();
This works for a particular case, but it won't solve your general issue, because member pointers contain the class they refer to as part of the definition. That is, the following two variables are of entirely different types:
B (Foo::* first_variable)() = Foo::some_function;
B (Bar::* second_variable)() = Bar::some_function;
Even though both functions can produce a B when called without arguments, the two values operate on different classes and therefore you can't assign a value of one type to a variable of the other type. This of course rules out storing these different types in a single STL container.
If you're committed to storing these in a container, you'll have to go with a functor-based solution like Charles Salvia proposes.
If I understand you correctly, you're going to have a class like:
struct Foo
{
int bar();
};
And the user will input a string like "Foo::bar", and from that string you need to call the member function Foo::bar?
If so, it's rather awkward to code a flexible solution in C++, due to the static type system. You can use an std::map where the key is a string, and the value is a member function pointer, (or std::mem_fun_t object), but this will only work on a single class, and only on member functions with the same signature.
You could do something like:
#include <iostream>
#include <map>
#include <functional>
struct Foo
{
int bar() { std::cout << "Called Foo::bar!" << std::endl; }
};
int main()
{
std::map<std::string, std::mem_fun_t<int, Foo> > m;
m.insert(std::make_pair("Foo::bar", std::mem_fun(&Foo::bar)));
Foo f;
std::map<std::string, std::mem_fun_t<int, Foo> >::iterator it = m.find("Foo::bar");
std::mem_fun_t<int, Foo> mf = it->second;
mf(&f); // calls Foo::bar
}
just found(using google) a topic to the same question I had with an answer.
What is the simplest way to create and call dynamically a class method in C++?
I didn't try it yet but makes sense, I will ask again later if it doesn't work
ty!
Joe
I must call the right function of an instance of a class.
You need to call a specific method on an existing instance, or you need to create an instance of the appropriate type and call the method?
If it's the former, then you need a std::map or similar that lets you look up instances from their names.
If it's the latter, that's basically what serialization frameworks need to do in order to create the correct type of object when de-serializing, the object that knows how to read the next bit of data. You might take a look at how the Boost serialization library handles it:
boost.org/doc/libs/1_40_0/libs/serialization/doc/serialization.html
Are you doing this in some kind of tight loop where you need the efficiency of a good map? If so, then member function pointers (as you linked to above) is a good way to go. (At least it is after you work around the problem #Tim mentioned of keeping member function pointers to different types in the same collection ... let the language abuse begin!)
On the other hand, if this is in code that's user-driven, it might be more legible to just be totally uncool and write:
if( funcName=="A.b" )
{
A a;
a.b();
} else
// etc etc etc
For the higher-performace case, you can supplement the same approach with a parse step and some integer constants (or an enum) and use a switch. Depending on your compiler, you might actually end up with better performance than using member function pointers in a map:
switch( parse(funcName) )
{
case A_b:
{
A a;
a.b();
}
break;
}
(Of course this breaks down if you want to populate your list of possibilities from different places ... for example if each class is going to register itself during startup. But if you have that kind of object infrastructure then you should be using interfaces instead of pointers in the first place!)