c++ difference between std::string name and std::string &name - c++

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.

Related

Get class pointer name from within its method?

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");

Using Variables In Classes (C++ help)

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.

consts inside classes?

Hi I was trying to define a constant inside a class, doing it the normal or usual way doesnt seem to work
class cat
{
public:
cat();
~cat();
private:
static const int MAX_VALUE = -99999;
int Number;
public:
void OrganizeNumbers();
void SetNumbers();
};
So the solution I found after doing some research was to declare it as static but what does this means and also I want to ask it is really necesary to declare a constant, becuase as you can see it is private right? i means it can only be accessed by the class methods so why to set a constant and also I read that using static only allows you to use integral type so its actually a dissavantage... if you are thinking to make a game.
static means that the member will be shared across all instances of your object.
If you'd like to be able to have different values of a const member in different instances you'll need to use a initialization list to set it's value inside your constructor.
See the following example:
#include <string>
struct Person {
Person (std::string const& n)
: name (n)
{
// doing: 'name = n' here is invalid
}
std::string const name;
};
int main (int argc, char *argv[]) {
Person a ("Santa Claus");
Person b ("Bunny the Rabbit");
}
Further reading
[10] Constructors - parashift.com/cpp-faq
10.1 Construct Initialization List
Initialization Lists in C++
1) Declare it "private" if you're only going to use MAX_VALUE inside your class's implementation, declare it under "public" if it's part of your class's interface.
2) Back in "C" days, "static" was used to "hide" a variable from external modules.
There's no longer any need to do this under C++.
The only reason to use "static" in C++ is to make the member class-wide (instead of per-object instance). That's not the case here - you don't need "static".
3) The "const" should be sufficient for you.
4) An (older-fashioned) alternative is to define a C++ enum (instead of a "const int")
There seems to be some confusion of ideas here:
A static member doesn't have to be an integral type, the disadvantage you mention does not exist.
const and private are unrelated, just because a member can only be accessed from instances of a given class, doesn't mean that nothing is going to change it.
Being const-correct guards against runtime errors that may be caused by a value changing unexpectedly.
you have to init the const attribute in the constructor with :
cat() : MAX_VALUE(-99999) {}
(which was declare as const int MAX_VALUE;)

instantiation in c++

First of all, I would like to notify you, I have definetly searched for answers about my following question, but im a complete newbie to C++.
I am coming from the luxurious life of C# and Java, now trying to pick up a thing or two about c++
The question is about instantiation.
I use code::block as my IDE of choice.
Currently I am just playing around with what in C# (which I'm actually quite familiar with and have written several applications in) is
2 classes
the class containing main and Person
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Models.Person;
namespace ConsoleApplication1
{
class Program
{
static void Main(string[] args)
{
Person person = new Person();
Console.WriteLine(person.getName());
}
}
}
and the person class:
namespace ConsoleApplication1
{
public class Person{
private string name = "Bob";
public string getName(){
return name;
}
}
}
(dont mind bad or right written syntax, its just to simulate what i want to achieve)
I want to achieve the same in C++
I have looked up, and learned about headers to some extent, and picked up a bit of the syntax. This is what I have right now.
main.cpp
#include <iostream>
using namespace std;
int main()
{
Person person;
cout << person->getName() << endl;
}
Person.h
#ifndef PERSON_H
#define PERSON_H
#include <string>
class Person
{
public:
Person();
virtual ~Person();
std::string getName();
protected:
private:
};
#endif // PERSON_H
player.cpp
#include "Person.h"
#include <string>
using std::string;
Person::Person()
{
//ctor
}
Person::~Person()
{
}
string Person::getName()
{
return name;
}
Considering the above code, I have multiple questions.
I never found a good source that showed me whether I should instantiate using Person person; or Person person = new Person();
Which one of the two is the one I'm supposed to use?
And another question I'm dying for is, do I define class members in the header file or in the class file?
Currently I'm recieving the following errors:
'person' was not declared in scope and expected ';' before person
I'm not nescesarily asking you to resolve my errors, I'll manage that upon recieving answers on my questions.
As larsmans said, Person person and Person *person = new Person() are result in the new Person instance being allocated in the stack/heap respectively.
What this means for you (and this is the answer to the "which should I use?" question) is that in the first case, the memory for the object is managed automatically (that's the good news). The bad news is that the lifetime of the object is also managed automatically, and you don't have any control over it. As soon as the person variable goes out of scope, the object is destroyed. Period.
In the second case (new), the object's lifetime is managed by you (it will exist until you do delete person). The bad news here is that the memory is also managed by you: if you don't ever do delete person, the memory allocated to that object will leak. It won't make any difference if you have no reference to person anywhere in scope anymore.
So if the lifetime is long enough for you, don't use a pointer. Otherwise, you will have to.
For class members:
They have to be declared in the header file; if you don't declare them and try to use them, you will get a compiler error.
They may optionally be defined in the header file; if not, you can define them in the .cpp file; if you don't define them anywhere and try to use them, you will get a linker error.
Generally definitions should go to the .cpp file, but it's OK if you define really short methods in the header.
Addendum
Of course there are plenty of details I didn't touch upon in this short answer. Here's a few important ones you might want to look into:
Using new/delete to manage memory can also give birth to lots of other problems apart from memory leaks; dangling pointers (which point to memory that has been released, and therefore cannot be used anymore -- this is essentially the "reverse" error than a memory leak) is probably #2 on the list.
Using some kind of smart pointer will help in achieving "C# semantics": whenever the last smart pointer to some memory goes out of scope, the memory will be released automatically on the spot (if it points to an object the destructor will run at this time; this is called deterministic destruction, C# does not have it and it has to try to emulate it with IDisposable). There are very good and mature smart pointers you can use in C++0x and Boost.
In C++, all types work like C# value types. If a takes up 2MB of memory and you do b = a, you just had the compiler populate a brand new 2MB of memory with a copy of a (and probably do a lot of extra work to achieve that). If that is not your intention, you need to store a pointer or a reference to a instead.
Person person will construct an object on the stack. Person *person = new Person will construct it in memory on the free store (heap; note the * because you need a pointer). This differs from C#, where you'd choose between struct and class to get either stack or heap allocation. In C++, these keywords have a different meaning. If you choose to allocate on the heap, then you must later delete the object manually.
Implement small, performance-critical methods that are not subject to change in the header. Put everything else in the implementation file.
(Please don't put a using directive at top-level in a header file.)
The equivalent of your C# code would be this:
#include <iostream>
#include <string>
class Person
{
std::string name;
public:
Person() : name("Bob"){}
std::string getName() { return name; }
};
int main()
{
//automatic variable; doesn't need new!
Person person;
std::cout << person.getName() << std::endl;
//pointer ; need to use new
Person *pPerson = new Person(); //it allocates memory!
std::cout << pPerson->getName() << std::endl;
delete pPerson; //it deallocates the memory!
}
Output:
Bob
Bob
See the online demo : http://ideone.com/cM0uU
The main distinction concerning Person is whether you want value
semantics or reference semantics---for entity objects, reference
semantics are necessary (since they preserve identity), but for
most others, value semantics are preferrable. In your example,
Person could easily be made to work with value semantics, but in
a more realistic case, it would depend on the role of the class
in the application.
Anyway, if you define value semantics, you do not (almost
never) allocate instances dynamically. You define them as local
variables, copying them as needed, and let the compiler take
care of the rest. You also make sure that copy, assignment and
the destructor do what you want---in modern C++, this is usually
the case, as your application level objects will be based on
lower level objects with copy constructors, assignment and
destruction which do the right thing, but this didn't used to be
the case, and it isn't always the case today. If you want
entity semantics, you have to decide what the lifetime of the
entity should be. (I'd say just as you would in other
languages, but many Java and C# programmers forget this. And
often get away with it. You won't get away with it, ever, in
C++.) Entity objects are normally created using new, and must
be destructed when their lifetime ends.
It's also good practice to ban copy and assignment of entity
objects (except maybe to provide a clone function) in C++.
Concerning the second point: the complete class definition must
be in a single place; you can't reopen the definition once
you've closed it with the last curly brace. This means that
member function declarations (but not the definitions) and
member data must be present in the class definition, in the
header file. It's best to put as little as possible in the
header file, however, and the definitions of the functions (the
implementation) normally belongs in the source file.
(There are exceptions to all of these rules, but they're a good
starting point.)
In the beginning of main.cpp you must also #include "Person.h".
In java, everything is a reference type, and so has to be instantiated using new, which creates a value type and returns a reference to it. In c++, the basic type is a value type, and a reference type similar to a java one looks like Person* person; You should really drop everything you know from java when going into c++ and start from the basics, it really can be very confusing to go from high to low level programming
If you're coming from C#, this explaination might be helpful:
In C++ the declaration/definition of a type doesn't say whether it is a "value type" or a "reference type". The only difference between 'struct' and 'class' is that members are private by default in 'class'. It's how you use it that determines this.
When you declare a Person, you are creating it as a "value type".
When you declare a Person*, you are creating a pointer (a reference type in C#) to a Person which normally is allocated on the heap with new. References (i.e. Person&) in C++ are like ref Person in C#.
As James points out in his comment, getting a good C++ book is your best bet.
The errors you're getting come from not using #include "Player.h" (assuming that's what you named the header file containing the declaration for the class Person since that's what your #define PLAYER_H suggests). After that, it'll complain because you're using person->getName() instead of person.getName(). The -> is used with pointers you should probably read up a bit more on this.
As for defining class members, if I understand the terminology correctly, you should declare them in your header file. They are then defined, often implicitly, in the constructor in your class file.
class MyClass {
int myVar; // Declare the variable
public:
MyClass(int inVar); // Declare the constructor function
};
And then in the class file:
MyClass::MyClass(int inVar) // Define the constructor function
: myVar(inVar) // Define the variable
{
}
Of course, you can do both in the header file and it's appropriate to do so sometimes.
class MyClass {
int myVar; // Declare the variable
public:
MyClass(int inVar) // Declare and define the constructor function
: myVar(inVar)
{}
};

C++ passing reference to class' private variable - compiler issue?

Is the passing by reference of a private variable in a class to be directly changed outside that class acceptable practice? Or is this something that the compiler 'should' pick up and prevent?
Example:
//-------------------------------------------
class Others
{
public:
Others() {};
void ChangeIt(string &str) { str = "Changed by Others"; }
};
//-------------------------------------------
class Locals
{
private:
string PrivateString;
public:
Locals() { PrivateString = "Set by Locals"; };
void VisitOthers() { Others o; o.ChangeIt(PrivateString); }
const string GetString() { return PrivateString; }
};
//-------------------------------------------
int main(void)
{
Locals lo;
cout << lo.GetString() << "\n";
lo.VisitOthers();
cout << lo.GetString() << "\n";
return 0;
}
Output:
Set by Locals
Changed by Others
I need to do something like this using other/different objects, private to the owner class, but changeable by others when needed. Last thing I want is for this kind of practice to come back & byte me in the future.
What is essentially worrying me, is that I would like to view the class/struct as basically a pointer to a buffer, and the member's address as offsets into this buffer, so that even if you pass the pointer-value of a member it would be useless without the base-pointer of the class/struct to which it belongs. This is what I instinctively feel should be the case, so that the above example should not even be possible.
There is nothing to prevent, you pass your private member by reference. The function you are calling isn't accessing your private member, it is changing it's own argument (that happens to be the member of some class). The code is OK, but the important thing is that the function you called doesn't keep a reference to your private member.
As the designer of the class, C++ won't prevent you to hand out reference to class private members to anyone. It may however be advisable to restrict such access to only authorized entities e.g. friends, in which case access to such private members is not really a big concern as it is 'by design'.
EDIT 2:
The mutating version of operator[] for a class also typically provides an interface for the external entities to modify the private members.
This is not good practice.
If you want other objects to modify your object, then go for
Friend classes and Friend functions
Passing private members is totally okay. You would indicate that VisitOthers() does not change your object by making it a const method. If the method was:
void VisitOthers() const {Other o; o.visit(PrivateString);}
you would get a compiler error, because you would only allowed to pass PrivateString as a const object. It is very important though that you indicate by const and your comments which methods actually change the state of your object.