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");
Related
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;
}
Assume I have a program that works according to the following hierarchy:
And I have a linked list container of Human * which I am iterating over with std::list<Human *>::iterator human. The following iterator can point either Men, Women and Flying Men. Is there a possibility, maybe something like typeid(*human).name() that will return the name of the class that the pointed object belongs to? When I use typeid.name() I get class Human *.
Selecting an execution path in runtime based on type inspection is bad since it places knowledge where it shouldn't be and makes it harder to add new types since all checks have to be expanded with the new type id.
Instead, define an interface that allows all types that need it create their own versions. Here is a compilable example that you can copy and play around with. Notice that adding a new type that should be serialized doesn't change any code in existing classes and no new tests are needed. And, as a bonus, everything is type checked at compile time, making it impossible to add a call with an object of the wrong type.
#include <iostream>
#include <list>
#include <boost/foreach.hpp>
class Output {
public:
// Whatever operations needed
int Write(int value) {
std::cout << value << std::endl;
return 0;
}
};
class Human {
public:
virtual ~Human() {}
virtual int Serialize(Output& output) = 0;
};
class Men : public Human {
public:
int Serialize(Output& output) {
return output.Write(17);
}
};
class Women : public Human {
public:
int Serialize(Output& output) {
return output.Write(42);
}
};
int main(int argc, char* argv[]) {
Output output;
Men men1;
Men men2;
Women women1;
Women women2;
std::list<Human*> toSerialize;
toSerialize.push_back(&men1);
toSerialize.push_back(&women1);
toSerialize.push_back(&men2);
toSerialize.push_back(&women1);
BOOST_FOREACH(Human* human, toSerialize) {
human->Serialize(output);
}
return 0;
}
You can use typeid on the object **human itself, rather than the pointer, which always has type Human* whatever it points to. As long as Human is polymorphic (that is, it declares at least one virtual function), that will give you the type info for the dynamic type of the object.
Note that the name is not necessarily human-readable, or even unique; my compiler gives the mangled name 3Man if the pointer points to type Man, and other compilers may give other nastiness. If you want a nice human-readable name, you'll have to declare your own virtual member function to return one.
No. Typeinfo is the best reflection you're going to get. If you really need this, make a virtual member function that returns the proper names.
Yes, but your classes must have a virtual function. The best place would be to use a virtual destructor, since it is most likely needed sooner rather than later anyway.
Also note that typeid is not defined to give you a readable name. If it does with the compilers you currently target, great. If not, you may need to add a virtual function like const std::string &className() const to get what you want.
This question already has answers here:
minimal reflection in C++
(4 answers)
Closed 8 years ago.
I want to create an object of a class with name of a string already known by me i.e dynamically.
Suppose i have a class A
and a string str="ab"
so I should create an object A ab;
but I can't specify "ab" as it should be like A str,as str may vary dynamically.
You could use a map data structure, with the key being name of the class, and the value being a factory class for creating the object, or a pointer to a function which when run, will return the object. However, you may need to cast the constructed object to your desired type.
Example (apologies for my rusty C++ code):
First, we have an interface for a factory class
class IObjectFactory
{
public:
virtual ~IObjectFactory() {}
virtual void* Create() = 0;
};
Then, a concrete implementation. I'll just do inline.
class ConcreteObjectFactory : public IObjectFactory
{
public:
void* Create() { return new ConcreteObject(); }
};
Now for the map.
using namespace std;
map<string, shared_ptr<IObjectFactory> > classMap;
// register the type
classMap["concreteObject"].reset( new ConcreteObjectFactory() );
// using it, albeit you take all kinds of risks if the string is not found
// or points to the wrong type.
ConcreteObject* o =
static_cast<ConcreteObject *>( classMap["concreteObject"]->Create() );
There are many ways to improve this answer. For those interested, I'll suggest checking out the chapter on RTTI in "C++ for Games Programmers"
The name of a variable is not part of the program, or more precisely, the name doesn't exists within memory.
It is just a "handle" or a "sign" to let the programmers easily access the variable,
ie. find where the content of the variable resides in memory.
In other words, after a piece of code has been compiled to object file, the names doesn't exists any more.
In your case, "ab" is actually the content in memory, when "ab" emerges in memory, your program already runs at run-time, at that time there is no variable names at all.
It is possible in some circumstances to go from a name to a variable of that name that already exists (i.e. not create it now). That works with dlsym on UNIX or GetProcAddress on Windows. The symbol must be visible, thus a global and in Windows explicitly exported from the library. Beware of name "mangling" issues.
It is not possible to create one that way, other than, of course, the workaround of code-generation then, assuming a compiler is present, building that into a library.
In your case you probably want to use a map from a string to variables, and if you want the same map to be able to store different value types, you can use boost::any as the value type of your map.
I do not think it is possible .. if anyone gives you an answer, you can work around the problem in this way:
class A {
public:
A(const std::string& name) : name_(name) {}
inline std::string name() { return name_; }
private:
std::string name_;
}
in this way you have an implicit conversion from string to A, so:
std::string className = "myName";
std::cout << (A)className->name(); /* print "myName" */
Otherwise you could use a map data structure as suggest Extrakun.
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.
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.