g3d
g3d

Reputation: 451

Using string reference

I have a class like that.I want to use reference for string but it doesnt work.How can i use string& ?

#include <string>
using namespace std;
class T
{
public:
    T(string& s);
private:
    string s;
};

T::T(string& s)
{
    this->s = s;
}
int main(void)
{
    T t("Test Object");
    return 0;
}

Error : 'T::T(std::string &)' : cannot convert parameter 1 from 'const char [12]' to 'std::string &'

Upvotes: 5

Views: 6426

Answers (5)

masoud
masoud

Reputation: 56549

Use const :

class T
{
public:
    T(const string& ss);
private:
    string s;
};

T::T(const string& ss) : s(ss)
{
}

"Test Object" will be constructed as a const string before passing to T's constructor, so the constructor has to accept a const string.

Upvotes: 6

Mr.C64
Mr.C64

Reputation: 43044

In C++98/03, if you have a class that is not cheap to copy (e.g. an int or a double are cheap to copy, a std::string isn't, since its copy can involve allocating new heap memory, copying characters from source to destination, etc.), then the rule is to pass by const reference const std::string&:

class T
{
public:
    T(const string& s); // <--- const string&
private:
    string m_s;
};

And then in constructor do:

T::T(const string& s)
   : m_s(s)
{}

However, in C++11, where move semantics is available, the new rule seems to be: if you need a copy (and the object is cheap to move, as it normally should be), pass by value and move from the value:

T::T(string s)             // pass by value
   : m_s( std::move(s) )   // and move from the value
{}

(The optimal thing would be to offer a couple of overloads, passing by const & and passing by value, but probably this is not necessarily in all applications, but only when you need to squeeze performance.)

Note that when you don't need a copy, and just need to observe the parameter, the usual C++98/03 pass by const & rule is still valid.

Upvotes: 2

Nicholas Wilson
Nicholas Wilson

Reputation: 9696

You're not passing in a std::string. As it says, it can't convert from const char array to string-ref. Change the constructor to take a const-ref and it'll work. This is because a temporary string will have to be created from the char-array, and you can only make const-references to temporaries to stop you getting confused (if you modify the temporary, the changes are just going to be discarded, so the language stops you from doing that).

Upvotes: 2

LihO
LihO

Reputation: 42133

The constructor you defined takes a std::string by reference:

T::T(std::string& s)
{
    this->s = s;
}

thus the most straightforward thing to do would be to create a std::string object, that will be passed to this constructor:

std::string s("Test Object");
T t(s);

But since your constructor doesn't change the std::string you pass to it (it is just used to set the value of T's data member) you should pass const reference: T::T(const string& s). Also instead of letting the data member s being constructed and assigning another string into it later, it would be better if you construct this member directly within an initialization list:

T::T(const std::string& str) : s(str) { }

Upvotes: 2

bash.d
bash.d

Reputation: 13217

References need to be intialized using the initialiser-list of the constructor. Change your constructor to:

T::T(string& s) : s(s)
{
}

Additionally define your member s as std::string& s to be able to take a reference.

Maybe change the name of s to avoid ambiguities.

See this entry on SO.

Upvotes: 0

Related Questions