第 19.3 节在一个主要关注运算符重载的章节中介绍了字符串表示,特别是特殊运算符 []
、->
和 ()
。它将 copy_from()
作为辅助函数实现如下:
void String::copy_from(const String &x)
// make *this a copy of x
{
if (x.sz <= short_max)
{
memcpy(this, &x, sizeof(x);
ptr = ch;
}
else
{
ptr = expand(x.ptr, x.sz+1);
sz = x.sz;
space = 0;
}
}
类接口(interface)如下所示:
#ifndef STRING_EXERCISE_H
#define STRING_EXERCISE_H
namespace simple_string
{
class String;
char *expand(const char *ptr, int n);
}
class String
{
public:
String(); // default constructor x{""}
explicit String(const char *p); // constructor from C-style string
String(const String &s); // copy constructor
String &operator=(const String& s); // copy assignment
String(String &&s) // move constructor
String &operator=(String &&s) // move assignement
~String() // destructor
char &operator[](int n); // unchecked element access
char operator[](int n) const;
char &at(int n); // checked element access
char at(int n) const;
String &operator+=(char c) // add char c to the end
const char *c_str(); // c-style string access
const char *c_str() const;
int size() const; // number of elements
int capacity() const; // elements plus available space
private:
static const short short_max = 15;
int sz;
char *ptr;
union
{
int space; // unused allocated space
char ch[short_max+1]; // leave space for terminating 0
};
void check(int n) const; // range check
void copy_from(const String &x);
void move_from(String &x);
}
#endif
String::copy_from()
如何使用memcpy()
来复制类?我认为复制的类必须是普通可复制的(事实并非如此,因为 String
具有用户定义的构造函数、复制操作、移动操作和析构函数)。
最佳答案
How can
String::copy_from()
usememcpy()
to copy the class?
int
、char
和匿名 union 都可以轻松复制。因此,虽然您无法执行 String
的 memcpy
,但您可以执行其成员 的memcpy
。所有的人,同时。技术上正确的代码是:
memcpy(&this->sz, &x.sz, sizeof(x));
即为这个对象的成员复制存储的内存范围。这是由标准布局类型的规则保证的。对于标准布局类型,成员按定义顺序存储。因此,如果您从第一个开始,并覆盖所有对象的范围,那么应该复制成员。
但是,标准还规定标准布局类型的第一个成员子对象必须与对象本身具有相同的地址:
If a standard-layout class object has any non-static data members, its address is the same as the address of its first non-static data member.
这意味着 &this->sz
必须是 与 this
相同的地址,并且 &x.sz
必须与 &x
相同的地址。
所以去掉中间人:
memcpy(this, &x, sizeof(x));
这只是因为标准布局类型的规则才被允许。
一个更大的问题是 copy_from 从不检查self 赋值。 memcpy
不适用于重叠的内存范围。也许 operator=
和类似的函数已经检查过了。
关于c++ - 来自 "The C++ Programming Language 4th Edition"第 19.3.3.1 节的代码是否有效?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51386532/