5

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 &'

0

5 Answers 5

6

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.

Sign up to request clarification or add additional context in comments.

Comments

2

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

Comments

2

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).

Comments

2

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.

Comments

0

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.

3 Comments

The member s isn't a reference here.
But there is no reference initialized - it is a string ?
He just added contents, how would I know that?

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.