How to initialize a constructor using the Strings parameter as parameters?

I'm not sure I use the correct terminology, but the question is how to create a constructor that takes a string as a parameter?

I use const char * in the constructor instead of strings.

Normally I would do something like this:

 Name(const char* fName, const char* lName) : firstName(0), lastName(0) { char * temp = new char [strlen(fName) + 1]; strcpy_s(temp, strlen(fName) + 1, fName); firstName = temp; char * temp2 = new char [strlen(lName) + 1]; strcpy_s(temp2, strlen(lName) + 1, lName); lastName = temp2; } 

What if the constructor is:

  Name(const string fName, const string lName) { } 

Am I still initializing a base element? Do I still need to use string copying in the constructor base?

+7
c ++ string constructor
source share
4 answers

Use std::string and initializer lists:

 std::string fName, lName; Name(string fName, string lName):fName(std::move(fName)), lName(std::move(lName)) { } 

In this case, you do not need to use terribly bare pointers, you do not need to allocate memory, copy characters, and finally de-allocate. In addition, this new code has a chance to take advantage of the move rather than copy, since std::string is movable. It is also helpful to read this .

And so on....

+9
source share

I see that you have already accepted the answer, but I would like to expand the answers.

As deepmax said, if you walk by value, you can write your constructor to take advantage of the "movement semantics." This means that instead of copying data, it can move from one variable to another.

It is written as follows:

 class Name{ public: Name(std::string var): mem_var(std::move(var)){} std::string mem_var; }; 

Which seems like a good idea, but actually no more efficient than copy constructor

 class Name{ public: Name(const std::string &var): mem_var(var){} std::string mem_var; }; 

The reason for this is that in general it looks like this:

 auto main() -> int{ Name name("Sample Text"); } 

only one copy will be made in any case (see copy elision ), and in another case

 auto main() -> int{ std::string myname = "Hugh Jaynus"; Name name(myname); } 

2 copies will be made in the "effective" way of semantics of moving by value!

This is a good example of when to use the copy constructor (or pass-by-reference) should , rather than an example against it.


On the contrary ...

If you write an explicit constructor that uses move semantics, you can get an effective solution regardless of the circumstances.

This is how I wrote out the class definition:

 class Name{ public: Name(const std::string &first_, const std::string &last_) : first(first_), last(last_){} Name(std::string &&first_, std::string &&last_) // rvalue reference : first(std::move(first_)), last(std::move(last_)){} std::string first, last; }; 

Then, when you use this class, you can decide when it is more efficient.

If we return to our examples, we can rewrite them to use the best or most efficient constructor:

 auto main() -> int{ // pass by reference best here Name myname("Yolo", "Swaggins"); // move most efficient here // but never use 'first' and 'last' again or UB! std::string first = "Hugh", last = "Jaynus"; Name yourname(std::move(first), std::move(last)); } 

Never take for granted that one solution is better than everyone else!

+6
source share

I use this:

 std::string fName; std::string lName; Name(const std::string &fName, const std::string &lName) : fName(fName), lName(lName) { } 

Using links saves the job of copying strings to a new object on the stack, it just passes a link to an existing string. When you assign them to class members, they will be copied.

+3
source share

if you want to save const char *, as constructor input types do.

 std::string fName; std::string lName; Name(const char *_fName, const char *_lName) : fName(_fName), lName(_lName) { } 

You can build std :: string from char constant.

0
source share

All Articles