标题说明了一切。但是,请将string
作为任何类的占位符。
std::string s1("hello"); // construct from arguments
std::string s2 = "hello"; // ???
std::string s3; // construct with default values
s3 = "hello"; // assign
我想知道s2
的语句是否与s1
或s3
相同。
发布于 2017-01-25 08:08:25
s2
的例子是copy initialization。它是初始化的,而不是作为s3
的情况分配的。
注意,对于std::string
,s1
和s2
的效果是相同的,因此将调用apporiate构造函数(即std::string::string(const char*)
)来构造对象。但是复制intialization和direct initialization (s1
的例子)有一个不同之处;对于复制intialization,不考虑显式构造函数。假设std::string::string(const char*)
声明为explicit
,这意味着不允许从const char*
到std::string
的隐式转换;那么第二种情况将不再编译。
复制初始化不像直接初始化那样允许:显式构造函数不是转换构造函数,也不考虑复制初始化。
发布于 2017-01-25 08:06:49
在这种情况下,s1
和s2
做的事情完全一样:它们都将构造函数调用为const char*
。(为了清晰起见,有些人更喜欢使用=
)。
对于s3
,调用默认构造函数,然后调用operator=
到const char*
。
发布于 2017-01-25 14:47:21
虽然所有三个方法的最终结果都是相同的(字符串将分配给变量),但是有一些基础上的差异比语法更深。我将详细介绍您的三个字符串所涵盖的所有三个场景:
第一种情况: s1是直接初始化的一个例子。直接初始化涵盖了许多不同的场景,您的定义如下:
使用非空括号大小的表达式列表进行初始化。
在这里,s1没有类数据类型,而是std::string
数据类型,因此将进行标准转换,将括号中的数据类型转换为s1的不合格版本,即const *char
。Cv-不合格意味着没有附加到变量上的限定符,如(Const)、或(易失性)。注意,在直接初始化的情况下,它比复制初始化要宽松得多,而复制初始化是s2的主题。这是因为复制初始化只引用由non_explicit (即隐式)的用户定义的构造函数和转换函数。另一方面,直接初始化考虑隐式和显式构造函数以及用户定义的转换函数.
接下来,第二个字符串s2是复制初始化的一个例子。简单地说,它将值从左侧复制到右侧。这是一个例子:
当非引用类型T的命名变量(自动、静态或线程本地)被声明时,初始化器由一个等号和一个表达式组成。
此方法所涵盖的过程是相同的。由于s2没有类数据类型,而是std::string
数据类型,因此它将使用标准转换将右侧字符串的值转换为左侧const *char
类型的值。但是,如果函数是显式声明的,则标准转换不能与复制初始化程序不同,代码的编译将失败。
参见一些代码示例,与2种类型的初始化相比较。这应能消除上面的任何混淆:
struct Exp { explicit Exp(const char*) {} }; // This function has an explicit constructor; therefore, we cannot use a copy initialization here
Exp e1("abc"); // Direct initialization is valid here
Exp e2 = "abc"; // Error, copy-initialization does not consider explicit constructor
struct Imp { Imp(const char*) {} }; // Here we have an implicit constructor; therefore, a copy initializer can be used
Imp i1("abc"); // Direct initialization always works
Imp i2 = "abc"; // Copy initialization works here due to implicit copy constructor
接下来是第三种情况,它甚至不是初始化的情况,而是分配的情况。正如您在注释中所说的,变量s3是用默认字符串初始化的。当您使用等号时,该字符串被替换为"Hello“。这里发生的情况是,当s3在string s3;
中声明时,将调用std::string
的默认构造函数,并设置默认的字符串值。当您使用=符号时,下一行中的默认字符串将被hello替换。
如果我们看哪一种跑步速度更有效,差别是很小的。但是,如果我们只执行以下操作,则s1运行的时间最快:
int main(void)
{
string a("Hello");
}
这需要以下时间和内存来编译和运行:
编译时间:0.32秒,绝对运行时间:0.14秒,cpu时间:0秒,内存峰值:3MB,绝对服务时间:0,46秒
如果我们查看以下列方式编码的字符串s2:
int main(void)
{
string a = "Hello";
}
那么程序运行所需的总时间是:
编译时间:0.32秒,绝对运行时间:0.14秒,cpu时间:0秒,内存峰值:3MB,绝对服务时间:0,47秒
使用复制初始化程序的运行时比直接初始化程序多运行0.01秒。差别是存在的,但却是微不足道的。
s3的第三种情况,如果按以下方式编码的话:
int main(void)
{
string a;
a = "Hello";
}
有一个完整的运行、编译时间和空间占用:
编译时间:0.32秒,绝对运行时间:0.14秒,cpu时间:0秒,内存峰值:3MB,绝对服务时间:0,47秒
我想在这里指出一点:第二个方法和第三个方法之间的运行时差异很可能是而不是0;相反,这是一个小于0.01秒的时间差,第三个方法花费的时间更长(s3)。这是因为它有两行代码要操作;一个是变量的声明,另一个是将字符串赋值给变量。
希望这能回答你的问题。
https://stackoverflow.com/questions/41846295
复制相似问题