在C ++

时间:2015-05-04 06:20:18

标签: c++ string arguments

在此代码中,方法名称为setname()。 在这个方法中我使用参数(Char * aname),参数“Name_Student”(当调用时)。

但是得到错误:“不推荐将字符串常量转换为'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);
}

我想知道为什么我收到此错误。任何人都可以解释不同的场景来理解这一点。

当我在调用

时在参数中使用cast时
.setname((char*)"Name_Student"); //Working Fine

当我将此字符串存储在数组中并传递该数组时,如

char name_s[] = "Name_Student";
.setname(name_s); // working fine

3 个答案:

答案 0 :(得分:1)

你应该在'char *'之前插入'const',但是这个问题已在这里得到解答:How to get rid of `deprecated conversion from string constant to ‘char*’` warnings in GCC?

答案 1 :(得分:1)

您正在寻找的内容可能已经回答here

此处还回复了我在问题下方发布的关于字符串的评论:

在两个C / C ++中,您可以选择是通过引用还是值传递。有两种方法可以做到这一点 - *(指向)运算符和&amp; (地址)运营商。但是,在您的情况下,使用值传递(而不是通过引用)是完全可以的:

#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);
}

如果你真的想通过引用来进入整个传递,你可以像这样轻松地修改setname()函数(你还必须用 string * name 修改名字成员,并且带有 return * name )的getname():

void setname(string& name) { this->name = name; }

在这种情况下可以调用

astudent.setname("Name_Student");

是不可能的,您必须先创建对象,然后将其传递给函数:

string newName = "Name_Student";
astudent.setname(newName);

如果你想在类外更改名称,这很有用,但是它可能被视为违反OOP原则的东西,因为改变对象的内容应该只通过它代表例程的类严格定义而不是就像那样。

以下是代码的重做,其中有一个小例子来说明我的意思:

#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);
}

上面代码的输出将是:

Name_Student
Name_StudentLALALA

然后在你的情况下我不相信你需要通过引用传递。还有一些建议 - 在C ++编程时尝试使用C ++提供的功能。虽然当然有一种情况,你可能想要坚持旧的char *做事情的方式,但它的编码风格很差。 std :: string 还提供 c_str()函数,该函数返回一个C字符串(有关详细信息,请参阅here)。

答案 2 :(得分:0)

除非您有特定原因要使用char*,否则应使用std::string。我认为使用std::string*的想法是一个可怕的想法,因为学生姓名的生命周期与学生对象是分开的。请考虑以下代码:

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;
}

如果您尝试使用学生的姓名,您将引用一个不再存在的对象。您可以尝试使用:

student s = get_student();
cout << s.getname() << endl;

我认为最好的选择是使用string作为名称。这样您就不必担心内存分配和生命周期管理。你还应该有一个构造函数,而不仅仅是setter(除非你要去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; }
};

如果您的setname将参数作为const string&,那么您仍然可以使用setname("Name"),因为这将创建一个可以绑定到const引用的右值。

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