std::string 类成员应该是指针吗?
不
那么为何不?
因为 std::string 与标准库中的所有其他对象一样,以及 c++ 中所有其他编写良好的对象都被设计为被视为一个值。
它可能会或可能不会在内部使用指针 - 这不是您关心的问题。您需要知道的是,当将其视为一个值时,它的编写精美并且表现得非常高效(实际上比您现在可能想象的要高效)......特别是如果您使用移动构造。
我觉得我想复制那个字符串,但我不知道什么时候决定。我应该复制向量吗?套?地图?整个 JSON 文件...?
是的。一个编写良好的类具有“值语义”(这意味着它被设计为被视为一个值)——因此被复制和移动。
曾几何时,当我第一次编写代码时,指针通常是让计算机快速完成某事的最有效方式。如今,借助内存缓存、管道和预取,复制几乎总是更快。(对真的!)
在多处理器环境中,除了最极端的情况外,复制速度要快得多。
如果我有一个 10 兆字节的文件作为 const 字符串,我真的不想复制它。
如果您需要它的副本,请复制它。如果你真的只是想移动它,那么std::move
它。
如果我要更新 100 个对象,将 5 个字符的 const 字符串传递给每个对象的构造函数,那么它们都不应该拥有所有权。可能只是复制字符串。
一个 5 个字符的字符串复制起来非常便宜,你甚至不应该考虑它。复制它。信不信由你,std::string
在编写时充分了解大多数字符串都很短,而且它们经常被复制。甚至不会涉及任何内存分配。
所以(假设我没有完全错)很明显在课堂之外做什么,但是当你设计类 GenericTextHaver 时,你如何决定文本拥有的方法?
以最优雅的方式表达代码,简洁地传达您的意图。让编译器决定机器代码的外观——这是工作。成千上万的人付出了他们的时间来确保它比以往任何时候都更好地完成这项工作。
如果您只需要一个在其构造函数中采用 const 字符串的类,并允许您从中获取具有相同值的 const 字符串,那么您如何决定如何在内部表示它?
几乎在所有情况下,都存储一份副本。如果 2 个实例实际上需要共享相同的字符串,那么请考虑其他内容,例如std::shared_ptr
. 但在这种情况下,他们可能不仅需要共享一个字符串,因此“共享状态”应该封装在其他对象中(理想情况下具有值语义!)
好的,停止说话 - 让我看看这门课应该是什么样子
class X {
public:
// either like this - take a copy and move into place
X(std::string s) : s(std::move(s)) {}
// or like this - which gives a *miniscule* performance improvement in a
// few corner cases
/*
X(const std::string& s) : s(s) {} // from a const ref
X(std::string&& s) : s(std::move(s)) {} // from an r-value reference
*/
// ok - you made _s const, so this whole class is now not assignable
const std::string s;
// another way is to have a private member and a const accessor
// you will then be able to assign an X to another X if you wish
/*
const std::string& value() const {
return s;
}
private:
std::string s;
*/
};