Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/string/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 以下声明之间的差异_C++_String - Fatal编程技术网

C++ 以下声明之间的差异

C++ 以下声明之间的差异,c++,string,C++,String,最近,我对使用字符串数据类型的new关键字感到困惑。你能试着澄清一下吗 以下字符串初始化之间有什么区别: (一) (二) 建议使用new关键字,因为字符串中的值是作为std::string的内部缓冲区存储在堆中的任何方式。如果有人解释它的存储位置就好了 返回字符串与返回字符串之间有什么区别* string* name() { string* name = new string("abc") ; return name; } string name() { string

最近,我对使用字符串数据类型的new关键字感到困惑。你能试着澄清一下吗

以下字符串初始化之间有什么区别:

(一)

(二)

建议使用new关键字,因为字符串中的值是作为
std::string
的内部缓冲区存储在堆中的任何方式。如果有人解释它的存储位置就好了

返回字符串与返回字符串之间有什么区别*

string* name()
{
    string* name = new string("abc") ;
    return name;
}

string name()
{
    string name = "abc";
    return name;
}

string
是在当前作用域中创建的实际字符串,当作用域退出时,它将被自动清除

void function() {
    { // a scope
        string test = "hi";
    }
    // test is destroyed here and cannot be used.
}
string*
是指向未绑定到当前作用域的字符串的指针。指针一开始是无效的(通常由用户分配
nullptr
,这意味着它不指向任何东西),您需要为它分配一个内存位置;如果不是,访问它将是一个错误。当您使用
new
并为指针指定一个值时,您就有了一个位于堆上而不在当前作用域中的字符串,您需要手动
删除它,否则内存就会泄漏。您可以将指针包装在智能指针中,使其自动删除自身

void function() {
    {
        string *test = new string("hi");
    }
    // test is *not* destroyed and memory was leaked
}

void function() {
    unique_ptr<string> test;
    {
        test = unique_ptr<string>( new string("hi") );
    }

} // test is deleted when the function exits and the unique_ptr goes out of scope.
还可以显式移动字符串

string A = "hello";
string B( std::move(A) );
// A is invalid, and B contains "hello"
通常,std::string本身不是用new创建的,而是它们所在的结构或类

在使用指针的示例中,我可能有一个特殊的类,可以传递给不同的函数:

class MyClass {
    string a; 
public:
    const string *function1() { return &a; }
    const string &function2() { return a; }
    string function3() { return a; }
}
MyClass::function1
给我一个指向字符串的常量指针,这意味着没有数据被复制,我只能读取字符串的值

MyClass::function2
基本上与function1做相同的事情,但它使用引用,引用类似于指针,但它们必须始终包含有效的目标。引用通常在C++中使用指针。< /P>
MyClass::function3
返回字符串的副本,外部函数可以对其进行修改,并且不会影响类内的字符串。

有几个原因使第二种方法优于第一种方法:

  • 最重要的原因是:
    字符串
    是一个
    字符串
    ,句点。
    字符串*
    可能指向
    字符串
    ,也可能是
    NULL
    /
    nullptr
    ,也可能指向内存中的随机位置。因此,您应该尽可能使用普通的
    字符串
    ,而不是
    字符串*
    ,因为使用它们不太容易出错

  • 声明一个
    字符串
    对象将其放置在堆栈上,这意味着当它离开作用域时将自动清除。使用
    new
    意味着您现在必须手动清理分配的内存

  • new
    是一个相对缓慢的操作。使用堆栈变量要快得多


string
将其数据存储在堆上时,在堆上分配
string
本身仍然会增加另一个间接级别

如果我们使用新操作符,对象将在堆内存中创建,引用指针将在堆栈中。以你为例,

string* name()
{
 string* name = new string("abc") ;
 return name;
}
name是存储在堆栈中的指针变量,它包含string对象的地址。实际对象存储在堆中。因此,它不会在方法执行后被销毁。调用方法将获得对象的地址,我们可以使用该地址引用它。我们需要使用'delete'关键字取消分配字符串对象内存

例:

如果我们在没有新操作符的情况下定义一个字符串,它将在堆栈中创建,并在方法执行结束时自动销毁。考虑这个例子,

string name()
{
  string name = "abc";
  return name;
}
这里将在方法名的堆栈框架中创建一个对象,在方法执行结束后,它将被销毁

使用上述函数的语句如下

 string a = name();
这里将调用string类的运算符=()方法,并在调用函数的堆栈框架中创建一个新对象


希望这会有所帮助

建议是创建对象,在真正需要指针之前不要使用指针。相对于指针,更喜欢对象而不是引用。我们什么时候需要使用字符串*?似乎我们可以避免在您的答案中使用字符串*这一误导:您说过“指针开始时无效……通常初始化为
nullptr
”。不,它不是:指针以未初始化的值开始(除非在特殊情况下,如
静态
),因此它可能是
空的
/
空的PTR
,但更可能不是。指针需要赋值。我想他想说的是,通常赋值给NULL POINTERR,意思是更清楚的userOK mukunda。顺便说一下,答案非常全面!
string* name()
{
 string* name = new string("abc") ;
 return name;
}
delete name;
string name()
{
  string name = "abc";
  return name;
}
 string a = name();