Reputation: 163
In this Code a method name setname(). In this method I am using parameter (Char *aname), argument "Name_Student" (When calling).
But getting error: "deprecated conversion from string constant to 'char*' [-Wwrite-strings]"
#include <iostream>
#include <string>
using namespace std;
class student
{
int rollno;
char *name;
public:
void setname( char *aname);
void setrollno(int arollno);
char getname() {return *name;}
int getrollno() {return rollno;}
};
void student::setname(char *aname)
{
name = aname;
}
void student::setrollno(int arollno)
{
rollno = arollno;
}
int main()
{
student astudent;
astudent.setname("Name_Student"); //Getting Error Here
astudent.setrollno(10);
astudent.getname();
astudent.getrollno();
return (0);
}
I want to know why I am getting this error. Can Anyone explain different scenarios to understand this.
When I am using casting in argument at the time of calling
.setname((char*)"Name_Student"); //Working Fine
When I am storing this string in an array and passing that array like
char name_s[] = "Name_Student";
.setname(name_s); // working fine
Upvotes: 0
Views: 986
Reputation: 2784
Unless you have a specific reason to use char*
you should use std::string
. I think the idea of using std::string*
is a terrible idea because the lifetime of the name of the student is separate from the student object. Consider the following code:
student get_student()
{
// get the student from the database
string name = "some name";
int rollno = 1;
student s;
s.setname(name);
s.setrollno(rollno);
return s;
}
If you then try to use the student's name you will be referencing an object that no longer exists. You can try it with:
student s = get_student();
cout << s.getname() << endl;
I think the best option is to use string
for the name. That way you don't have to worry about memory allocation and lifetime management. You should also have a constructor instead of just setters (unless you are going for POD).
class student {
int rollno;
string name;
public:
student(const string& name, int rollno): name(name), rollno(rollno) {}
void setname(const string& name) { this->name = name; }
void setrollno(int rollno) { this->rollno = rollno; }
const string& getname() { return name; }
int getrollno() { return rollno; }
};
If your setname
takes the argument as a const string&
then you can still use setname("Name")
because this will create an rvalue, which can bind to const reference.
int main(int argc, char *argv[]) {
student astudent("Student's Name", 10);
cout << "Roll #: " << astudent.getrollno() << '\n';
cout << "Name: " << astudent.getname() << '\n';
astudent.setname("New name");
cout << "Name: " << astudent.getname() << '\n';
string n{"Yet Another Name"};
astudent.setname(n);
cout << "Name: " << astudent.getname() << '\n';
return (0);
}
Upvotes: 0
Reputation: 9711
Probably what you are looking for is answered here.
Also here is a reply to the comment about strings that I have posted below the question:
In both C/C++ you can choose whether to pass by reference or value. There are two ways to do that - the * (pointer to) operator and & (address of) operator. However working with pass by value (not by reference) is totally okay in your case:
#include <iostream>
#include <string>
using namespace std;
class student
{
int rollno;
string name;
public:
void setname(string name) { this->name = name; }
void setrollno(int rollno) { this->rollno = rollno; }
string getname() { return name; }
int getrollno() { return rollno; }
};
int main()
{
student astudent;
astudent.setname("Name_Student"); // here you pass by value
astudent.setrollno(10);
astudent.getname(); // name is set, so everything is okay :)
astudent.getrollno();
return (0);
}
If you really want to go into the whole pass by reference thing you can easily modify the setname() function like this (you'll also have to modify the name member with string* name and the getname() with return *name):
void setname(string& name) { this->name = name; }
In this case however a call like
astudent.setname("Name_Student");
is not possible and you have to first create the object and then pass it to the function:
string newName = "Name_Student";
astudent.setname(newName);
This is useful in case you want to change the name outside the class however it might be viewed as something against the principles of OOP since altering an object's content should be done only via some strictly defined by the class it represents routines and not just like that.
Here is a redo of your code with a small example to illustrate what I mean:
#include <iostream>
#include <string>
using namespace std;
class student
{
int rollno;
string* name; // very important! otherwise you will just store a COPY of the new name instead of a reference to the object that was passed to setname()
public:
// here we pass by reference a string object!
void setname(string& name) { this->name = &name; }
void setrollno(int rollno) { this->rollno = rollno; }
string getname() { return *name; }
int getrollno() { return rollno; }
};
int main()
{
student astudent;
string str = "Name_Student";
astudent.setname(str); // we pass by reference here!
cout << astudent.getname() << endl;
str += "LALALA"; // because we have passed the string object by reference to the astudent object we can change its contents outside the class without using the setter provided by the class
cout << astudent.getname() << endl;
return (0);
}
The output from the code above will be:
Name_Student
Name_StudentLALALA
Then again in your case I do not believe you need any passing by reference. And a bit of advice - try to use the features provided by C++ when programming in C++. Although there are of course situation when you might want to stick to the old char* way of doing things in your case it just poor coding style. std::string also provides the c_str() function, which returns a C-string (see here for more information).
Upvotes: 1
Reputation: 343
You should insert 'const' before 'char*', however this question has already been answered here: How to get rid of `deprecated conversion from string constant to ‘char*’` warnings in GCC?
Upvotes: 1