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++。我知道相当多的Java和一些C语言_C++_String - Fatal编程技术网

是否将字符串值复制到类字段中? 我是新手,学习C++。我知道相当多的Java和一些C语言

是否将字符串值复制到类字段中? 我是新手,学习C++。我知道相当多的Java和一些C语言,c++,string,C++,String,我想做的是创建一个不可变的名称类,它接受一个字符串值,将该字符串复制到一个类字段中,然后最终将其散列到一个ID中,该ID可以比字符串更有效地进行解析 因为一般缺乏对C++字符串的了解,我正在打墙。这是我到目前为止所拥有的 #pragma once #include <string> class Name { public: Name(std::string s); ~Name(void); int getId(); std::string get

我想做的是创建一个不可变的名称类,它接受一个字符串值,将该字符串复制到一个类字段中,然后最终将其散列到一个ID中,该ID可以比字符串更有效地进行解析

因为一般缺乏对C++字符串的了解,我正在打墙。这是我到目前为止所拥有的

#pragma once

#include <string>

class Name
{
public:
    Name(std::string s);
    ~Name(void);

    int getId();
    std::string getName();

private:
    int id;
    std::string name;
};
所以我要做的是存储构造函数在“name”私有字段中传入的s的值。据我所知,必须创建一个新的字符串对象,然后必须将s的值复制到其中

我还认为参数s可以而且应该是字符串指针,而不是字符串对象(以防止发生不必要的复制)。如果我是对的,那么构造函数应该如下所示,对吗

Name::Name(std::string &s) { ... }
在这种情况下,传入名称时不需要做任何特殊的操作?即

Name n = new Name("Cody");
完全有效吗?实际上我不确定,因为据我所知,“Cody”是一个常量字符串或类似的东西

那么,如果我都在正确的轨道上,那么什么才是真正复制值的正确方法呢?我认为这是合适的,但我不确定

#include "Name.h"

Name::Name(std::string s)
{
    name = new string(s);
}

谢谢你的帮助,我知道这是一个基本问题,但我正在慢慢地进入C++世界。Cody

您应该在此处使用对
std::string
的常量引用

正如你所说,这将防止不必要的拷贝。。但为什么不仅仅是指针或常量指针呢

常量引用将允许您向函数传递一些参数,这些参数将隐式调用右侧的
std::string构造函数

简而言之,你可以这样做:

Name::Name(const std::string& s)
{
    this->name = s;
}

// Or even better..
Name::Name(const std::string& s):
    name(s)
{
}

int    main(void)
{
    Name    nick("hello");

    return 0;
}

您可以在其上找到关于每个
std::string的构造函数的信息。

您很接近了,您的代码经过一点按摩后可以是这样的:

class Name
{
public:
    Name(const std::string& s);  // add const and reference
    ~Name(void);

    int getId() cosnt;           // add const
    std::string getName() const; // add const

private:
    int id;
    std::string name;
};
Name.cpp

Name::Name(const std::string& s):name(s)
{
}
这里的
:名称
称为
成员初始值设定项列表

名称n=新名称(“Cody”);完全有效吗?实际上我不确定 因为据我所知,“Cody”是一个常量字符串或类似的东西 那个

不,
n
不是指针,它不像java那样需要为每个对象创建新对象。在C++中,你做< /P>
Name n("Cody");
这将调用
Name(const std::string&s)
初始化对象n并用“Cody”初始化名称字符串。 注意:变量
n
具有自动存储持续时间,如果超出范围将被销毁

要使
n
启用动态存储持续时间,您需要使用“新建/删除对”:

 Name *pn = new Name("Cody");
 delete pn;
或者使用智能指针,您无需调用
delete n\u ptras n_ptr在超出范围时也将被销毁:

 #include <memory>
 std::shared_ptr<Name> n_ptr(new Name("Cody"));

Name::Name(const std::string&s):Name(s){}
另外,在那里,
s
是一个引用,而不是指针。啊,我知道,这会接收常量字符串的地址,并使用初始化列表将其交给Name字段?如果我是对的,没有执行拷贝,name只指向s?差不多的地址,但它不是指针,而是引用。你可以看到不同之处。它接受字符串本身,而不是地址
name
获取
s
的副本。因此,当name对象被销毁时,当解构中的name对象时,我可能应该在name字段上调用delete?您没有动态分配对象名称,也没有分配std::strings。这里没有可手动删除的内容@如果你真的想用标准的库和C++来管理正确的内存管理思想,那么把你学到的关于指针和内存管理的大部分知识都用在C上,然后把它扔出窗口。如果你想看看你应该如何在新的框架下思考许多旧想法的例子,我强烈推荐你。非常感谢Whoz,看起来我习惯在Java和C中使用的许多样式都需要适当地搁置起来。这些都提供了大量信息。我很快就会读到这个报告。又来了,哇。因此,只有在将指针分配给新对象时才使用new?@CodySmith,是的,但在这种情况下,更喜欢使用智能指针。它为您管理内存,因此您不必自己删除它。谢谢。我至少熟悉智能指针(引用计数)背后的思想,我可以为此感谢Java。所以我不得不问,这个名称类最终将成为动态创建的其他类中的一个字段。我猜,因为包含Name对象的其他类必须使用对象指针,那么它们将在构造函数/解构器中调用new Name()和delete Name()?
 #include <memory>
 std::shared_ptr<Name> n_ptr(new Name("Cody"));
class TestName
{
public:
   TestName(const Name& n):name_(n){ }

private:
  Name name_;
};

TestName tn("Cody");