我是新手并学习C ++。我知道相当数量的Java和一些C.
我想要做的是创建一个不可变的名称类,它接受一个字符串值,将该字符串复制到一个类字段,然后最终将其哈希到一个可以比字符串更有效地解析的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;
};
和...
#include "Name.h"
Name::Name(std::string s)
{
}
所以我想要做的是存储s的值,由“name”私有字段中的构造函数传入。据我所知,必须创建一个新的字符串对象,然后必须将s的值复制到其中。
我也认为参数s可以而且应该是字符串指针而不是字符串对象(以防止发生不必要的副本)。如果我是对的,那么构造函数应该如下所示,对吧?
Name::Name(std::string &s) { ... }
在这种情况下,传递名字时不需要特别做什么? IE。
Name n = new Name("Cody");
完全有效吗?实际上我不确定,因为据我所知,“Cody”是一个常数字符串或类似的东西。
因此,如果我都在正确的轨道上,那么实际复制该值的正确方法是什么?我认为这是合适的,但我不确定。
#include "Name.h"
Name::Name(std::string s)
{
name = new string(s);
}
感谢您提前获得的帮助,我知道这是一个基本问题,但我正在慢慢地迈向C ++世界。 :) - Cody
答案 0 :(得分:3)
你很近,经过一点点按摩后你的代码就像这样:
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)
{
}
此处:name(s)
称为member initializer list
。
姓名n =新名称(“Cody”);完全有效吗?其实我不确定 因为据我所知,“Cody”是一个常量字符串或类似的东西 这一点。
不,n
不是指针,它不像每个对象需要新的java。在C ++中,你做
Name n("Cody");
这将调用Name(const std::string& s)
初始化对象n并使用“Cody”初始化名称字符串。
注意:变量n
具有自动存储持续时间,如果超出范围,它将被销毁。
要让n
了解动态存储时间,您需要使用新/删除对:
Name *pn = new Name("Cody");
delete pn;
或使用智能指针,你不需要调用delete n_ptr;
,因为n_ptr在超出范围时也会被销毁:
#include <memory>
std::shared_ptr<Name> n_ptr(new Name("Cody"));
修改强>
要在其他类中使用Name类,在Name类中使用string时的方法相同,则不必使用指针。
class TestName
{
public:
TestName(const Name& n):name_(n){ }
private:
Name name_;
};
TestName tn("Cody");
答案 1 :(得分:1)
你应该在这里使用std::string
的常量引用。
正如你所说,它可以防止不必要的副本..但是为什么不只是指针或常量指针?
常量引用允许您向函数传递一些隐式调用右std::string constructor
的参数。
因此,简而言之,你可以这样做:
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;
}
您可以在cplusplus.com's sheet上了解每个std::string's constructors
。