Sar*_*rah 11 c++ string constructor
我不确定我使用的是正确的术语,但问题是我如何正确地创建一个将字符串作为参数的构造函数?
我习惯const char *
在构造函数中使用而不是字符串.
通常我会做这样的事情:
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;
}
Run Code Online (Sandbox Code Playgroud)
如果构造函数是这样的:
Name(const string fName, const string lName) { }
Run Code Online (Sandbox Code Playgroud)
我还在做基本成员初始化吗?我还需要在构造函数的基础上使用字符串副本吗?
mas*_*oud 12
使用std::string
和初始化列表:
std::string fName, lName;
Name(string fName, string lName):fName(std::move(fName)), lName(std::move(lName))
{
}
Run Code Online (Sandbox Code Playgroud)
在这种情况下,您不需要使用非常简单的指针,您不需要分配内存,复制字符并最终解除分配.此外,这个新代码有机会利用移动而不是复制,因为它std::string
是可移动的.阅读本文也很有用.
等等....
Cof*_*ode 11
我看到你已经接受了答案,但我想扩大答案.
正如deepmax所说,如果你通过值传递,你可以编写你的构造函数来利用"移动语义".这意味着它不是复制数据,而是可以从一个变量移动到另一个变量.
写得像这样:
class Name{
public:
Name(std::string var): mem_var(std::move(var)){}
std::string mem_var;
};
Run Code Online (Sandbox Code Playgroud)
这似乎是一个好主意,但实际上并不比复制构造函数更有效
class Name{
public:
Name(const std::string &var): mem_var(var){}
std::string mem_var;
};
Run Code Online (Sandbox Code Playgroud)
这是因为在一般用例中看起来像这样:
auto main() -> int{
Name name("Sample Text");
}
Run Code Online (Sandbox Code Playgroud)
只有一个副本可以用任何一种方式制作(参见copy elision),在另一种情况下
auto main() -> int{
std::string myname = "Hugh Jaynus";
Name name(myname);
}
Run Code Online (Sandbox Code Playgroud)
2个副本将以'高效'按值传递移动语义方式制作!
这是一个很好的例子,说明何时应该使用复制构造函数(或者通过引用传递),而不是使用它的示例.
反之...
如果编写一个使用移动语义的显式构造函数,无论在什么情况下都可以获得有效的解决方案.
以下是我将如何编写类定义:
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;
};
Run Code Online (Sandbox Code Playgroud)
然后当你使用这个类时,你可以决定何时更高效.
如果我们回到我们的示例,我们可以重写它们以使用最好或最有效的构造函数:
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));
}
Run Code Online (Sandbox Code Playgroud)
永远不要理所当然地认为一个解决方案比其他解决方案更好!
归档时间: |
|
查看次数: |
36114 次 |
最近记录: |