C++ 如何初始化一个以字符串为参数的构造函数?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/19800939/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How to initialize a constructor with that takes Strings as parameters?
提问by Sarah
I am not sure that I am using the right terminology, but question is how do I properly make a constructor that takes a string in as a parameter?
我不确定我使用的术语是否正确,但问题是我如何正确制作一个将字符串作为参数的构造函数?
I am used to having a const char *
in the constructor instead of strings.
我习惯于const char *
在构造函数中使用 a而不是字符串。
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 this:
如果构造函数是这样的怎么办:
Name(const string fName, const string lName) { }
Do I still do base member initialization? do I still need to use string copy in the base of the constructor?
我还做基本成员初始化吗?我还需要在构造函数的基础中使用字符串副本吗?
回答by CoffeeandCode
I see that you have already accepted an answer but I would like to expand upon the answers.
我看到您已经接受了一个答案,但我想扩展这些答案。
As deepmax said, if you pass by value you can write your constructor to take advantage of "move semantics". This means instead of copying data, it can be moved from one variable to another.
正如 deepmax 所说,如果您按值传递,您可以编写构造函数以利用“移动语义”。这意味着可以将数据从一个变量移动到另一个变量,而不是复制数据。
Written like so:
像这样写:
class Name{
public:
Name(std::string var): mem_var(std::move(var)){}
std::string mem_var;
};
Which seems like a good idea, but in reality is no more efficient than the copy constructor
这看起来是个好主意,但实际上并不比复制构造函数更有效
class Name{
public:
Name(const std::string &var): mem_var(var){}
std::string mem_var;
};
The reason this is, is because in the general use case that looks like this:
这是因为在一般用例中,如下所示:
auto main() -> int{
Name name("Sample Text");
}
only one copy will ever get made either way (see copy elision), and in the other case of
无论哪种方式,都只会制作一个副本(请参阅复制省略),而在另一种情况下
auto main() -> int{
std::string myname = "Hugh Jaynus";
Name name(myname);
}
2 copies will be made in the 'efficient' pass-by-value move semantics way!
将以“高效”的值传递移动语义方式制作 2 个副本!
This is a good example of when the copy constructor (or pass-by-reference) shouldbe used, not an example against it.
这是何时应该使用复制构造函数(或引用传递)的一个很好的例子,而不是一个反对它的例子。
On the contrary...
相反...
If you write an explicit constructor that makes use of move semantics you could get an efficient solution no matter the circumstance.
如果您编写使用移动语义的显式构造函数,则无论情况如何,您都可以获得有效的解决方案。
Here is how you might write out a name class definition with both constructors:
下面是如何用两个构造函数写出名称类定义:
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 the class the more efficient path should be taken.
然后,当您使用该类时,应该采用更有效的路径。
If we go back to our examples we can rewrite them to make use of the best or most efficient constructor:
如果我们回到我们的例子,我们可以重写它们以使用最好或最有效的构造函数:
int main(){
// 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 just take for granted that one solution is better than all others!
永远不要想当然地认为一种解决方案比所有其他解决方案都好!
回答by masoud
Use std::string
and initializer lists:
使用std::string
和初始化列表:
std::string fName, lName;
Name(string fName, string lName):fName(std::move(fName)), lName(std::move(lName))
{
}
In this case, you don't need to use terribly bare pointers, you don't need allocate memory, copy characters and finally de-allocate. In addition, this new code has chances to take advantages of moving rather than copying since std::string
is movable. Also it's useful to read this.
在这种情况下,您不需要使用非常裸的指针,不需要分配内存、复制字符和最终取消分配。此外,这个新代码有机会利用移动而不是复制的优势,因为它std::string
是可移动的。阅读此内容也很有用。
And so on....
等等....
回答by Martijn Courteaux
I'm used to do this:
我习惯这样做:
std::string fName;
std::string lName;
Name(const std::string &fName, const std::string &lName) :
fName(fName), lName(lName)
{
}
Using the references saves the work of copying the strings to a new object on the stack, it will just pass the reference to the existing string. Once you are assigning them to the class members, they will get copied.
使用引用可以节省将字符串复制到堆栈上的新对象的工作,它只会将引用传递给现有字符串。一旦您将它们分配给班级成员,它们就会被复制。
回答by Mark Hendrickson
if you want to keep const char * as your constructor input types do this.
如果您想保留 const char * 作为构造函数输入类型,请执行此操作。
std::string fName;
std::string lName;
Name(const char *_fName, const char *_lName) :
fName(_fName), lName(_lName)
{
}
You can construct a std::string from a const char.
您可以从 const 字符构造 std::string。