簡體   English   中英

在C ++中將字符串用作參數和參數或返回類型的正確方法是什么

[英]What is correct way to use string as an argument and parameter or return type in C++

在此代碼中,方法名稱為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);
}

我想知道為什么會出現此錯誤。 任何人都可以解釋不同的情況來理解這一點。

當我在調用時在參數中使用強制轉換時

.setname((char*)"Name_Student"); //Working Fine

當我將此字符串存儲在數組中並像這樣傳遞該數組時

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

您應該在'char *'之前插入'const',但是這里已經回答了這個問題: 在GCC中,如何擺脫從字符串常量到'char *'的過時轉換警告?

也許您在找什么在這里回答。

另外,這是我在問題下方發布的有關字符串的評論的回復:

在兩種C / C ++中,您都可以選擇通過引用還是通過值。 有兩種方法可以執行此操作-*(指向的指針)運算符和&(的地址)運算符。 但是,在您的情況下,按值傳遞(而不是按引用傳遞)完全可以:

#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修改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字符串(有關更多信息,請參見此處 )。

除非有特殊原因使用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);
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM