首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >‘`string s(“hello”);’和‘`string s=’hello‘之间有区别吗?

‘`string s(“hello”);’和‘`string s=’hello‘之间有区别吗?
EN

Stack Overflow用户
提问于 2017-01-25 08:03:58
回答 4查看 846关注 0票数 2

标题说明了一切。但是,请将string作为任何类的占位符。

代码语言:javascript
运行
复制
std::string s1("hello");  // construct from arguments
std::string s2 = "hello"; // ???
std::string s3;           // construct with default values
s3 = "hello";             // assign

我想知道s2的语句是否与s1s3相同。

EN

回答 4

Stack Overflow用户

回答已采纳

发布于 2017-01-25 08:08:25

s2的例子是copy initialization。它是初始化的,而不是作为s3的情况分配的。

注意,对于std::strings1s2的效果是相同的,因此将调用apporiate构造函数(即std::string::string(const char*))来构造对象。但是复制intialization和direct initialization (s1的例子)有一个不同之处;对于复制intialization,不考虑显式构造函数。假设std::string::string(const char*)声明为explicit,这意味着不允许从const char*std::string的隐式转换;那么第二种情况将不再编译。

复制初始化不像直接初始化那样允许:显式构造函数不是转换构造函数,也不考虑复制初始化。

票数 14
EN

Stack Overflow用户

发布于 2017-01-25 08:06:49

在这种情况下,s1s2做的事情完全一样:它们都将构造函数调用为const char*。(为了清晰起见,有些人更喜欢使用= )。

对于s3,调用默认构造函数,然后调用operator=const char*

票数 2
EN

Stack Overflow用户

发布于 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种类型的初始化相比较。这应能消除上面的任何混淆:

代码语言:javascript
运行
复制
    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运行的时间最快:

代码语言:javascript
运行
复制
    int main(void)
    {
        string a("Hello");
    }

这需要以下时间和内存来编译和运行:

编译时间:0.32秒,绝对运行时间:0.14秒,cpu时间:0秒,内存峰值:3MB,绝对服务时间:0,46秒

如果我们查看以下列方式编码的字符串s2:

代码语言:javascript
运行
复制
    int main(void)
    {
        string a = "Hello";
    }

那么程序运行所需的总时间是:

编译时间:0.32秒,绝对运行时间:0.14秒,cpu时间:0秒,内存峰值:3MB,绝对服务时间:0,47秒

使用复制初始化程序的运行时比直接初始化程序多运行0.01秒。差别是存在的,但却是微不足道的。

s3的第三种情况,如果按以下方式编码的话:

代码语言:javascript
运行
复制
    int main(void)
    {
        string a;
        a = "Hello";
    }

有一个完整的运行、编译时间和空间占用:

编译时间:0.32秒,绝对运行时间:0.14秒,cpu时间:0秒,内存峰值:3MB,绝对服务时间:0,47秒

我想在这里指出一点:第二个方法和第三个方法之间的运行时差异很可能是而不是0;相反,这是一个小于0.01秒的时间差,第三个方法花费的时间更长(s3)。这是因为它有两行代码要操作;一个是变量的声明,另一个是将字符串赋值给变量。

希望这能回答你的问题。

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/41846295

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档