I'm continuing my studies for uni with C++ and I'm running into some serious comprehension issues concerning pointers, const arguments and all the very basics of class implementations (which are so easy in Java compared to C++)
I usually work with Java, so C++ is very new to me.
This is my simple header for a class "Person":
#ifndef Person_h
#define Person_h
class Person
{
private:
char* name;
char* adress;
char* phone;
public:
Person();
Person(char const *name, char const *adress, char const *phone);
Person(const Person &other);
~Person();
void setName(char const *name);
char* getName() const;
void setAdress(char const *adress);
char* getAdress() const;
void setPhone(char const *phone);
char* getPhone() const;
};
#endif // !Person_h
And here the problem starts. Why should I use char pointers instead of actual char variables? I'm guessing it's some conventions to spare memory or to improve performance?
This is the way our professor codes and tries to make us understand the use of pointer and const
etc.
Now here's my implementation of the class:
#include "Person.h"
//Person.h class implementation
Person::Person()
{
Person::name = new (char[64]);
Person::adress = new (char[64]);
Person::phone = new (char[64]);
}
Person::Person(const char *name, const char *adress , const char *phone)
{
Person::name = new (char[64]);
Person::adress = new (char[64]);
Person::phone = new (char[64]);
setName(name);
setAdress(adress);
setPhone(phone);
};
Person::Person(Person const &other)
{
Person::name = new (char[64]);
Person::adress = new (char[64]);
Person::phone = new (char[64]);
setName(other.getName);
setAdress(other.getAdress);
setPhone(other.getPhone);
};
Person::~Person()
{
delete [] name;
delete [] adress;
delete [] phone;
};
void Person::setName(const char *name)
{
this->name = name;
};
char* Person::getName() const
{
return name;
};
void Person::setAdress(char const *adress)
{
this->adress = adress;
};
char* Person::getAdress() const
{
return adress;
};
void Person::setPhone(char const *phone)
{
this->phone = phone;
};
char* Person::getPhone() const
{
return phone;
};
We should learn to manually allocate memory to elements and try to take care of the overall memory management. Therefore the use of const arguments for the setter functions. I guess this is in order to not alter the element argument? I'm very confused, basically...
And my IDE (MS VisualStudio 2015) underlines the following line as error:
void Person::setName(const char *name)
{
this->name = name; //error
};
"a value of type 'const char *' cannot be assigned to an entity of type 'char *'"
Then why should I use const
when I can't assign these values? Or how can I "un-const" those, without making the member variable itself const
?
This whole matter is just one big confusion to me now.
EDIT: I have to use C-strings for my exams, that's in order to understand pointer and memory management referring to our prof.
In layman's terms, the reason why this->name = name;
does not work when name
is const and this->name
is non-const, is because your function is promising that the contents of name
will be treated as read-only, but by assigning this pointer to a non-const pointer you would then be free to modify the data as you please, thus breaking your promise.
Your teacher is obviously trying to teach you old-style C++ with pointers, (essentially, object-oriented C,) so you should not go ahead and replace char pointers with strings. Your teacher will probably be unhappy if you do that.
There is a number of reasons why we use char*
instead of char[]
.
One reason is efficiency: if it was possible to pass a char[]
, then the entire contents of that char[]
would need to be copied to the stack. When you pass a char*
, you are only copying the pointer to the characters, which is usually a single machine word.
Another reason is that it is actually impossible. The compiler has no built-in knowledge of the fact that your char[]
is zero-terminated so as to allocate enough stack space for it and copy it to the stack. The creators of the language preferred to not put such built-in knowledge in the language. Instead, they decided that a char[]
should be implicitly converted to char*
, so that from within your function you can receive it as a char*
and do what you want with it.
Another reason is that if your char[]
was just a bit too large, then your stack would overflow.
So, for all these reasons, when we want to pass values of types that are larger (or considerably larger) than machine words, we do not pass the values themselves, we pass pointers or references to them.