第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;
}
}
Run Code Online (Sandbox Code Playgroud)
类接口如下所示:
#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
Run Code Online (Sandbox Code Playgroud)
如何String::copy_from()使用memcpy()复制类?我认为复制的类必须是易于复制的(它不是,因为它String具有用户定义的构造函数,复制操作,移动操作和析构函数).
如何
String::copy_from()使用memcpy()复制类?
int,char和匿名工会都可以轻易复制.所以,当你无法执行memcpy的String,则可以执行memcpy其成员.所有这一切,都是一次性的.技术上正确的代码是:
memcpy(&this->sz, &x.sz, sizeof(x));
Run Code Online (Sandbox Code Playgroud)
它为该对象的成员复制存储的内存范围.这由标准布局类型的规则保证.对于标准布局类型,成员按定义顺序存储.因此,如果您从第一个开始,并覆盖所有对象的范围,那么应该复制成员.
但是,该标准还指出,标准布局类型的第一个成员子对象需要与对象本身具有相同的地址:
如果标准布局类对象具有任何非静态数据成员,则其地址与其第一个非静态数据成员的地址相同.
这意味着&this->sz必须在同一地址的this,而且&x.sz必须是相同的地址&x.
所以只是剪掉了中间人:
memcpy(this, &x, sizeof(x));
Run Code Online (Sandbox Code Playgroud)
仅允许这样做,因为标准布局类型的规则.
更大的问题是copy_from从不检查自我分配.memcpy不适用于重叠的内存范围.也许operator=和类似的功能已经检查了这一点.
| 归档时间: |
|
| 查看次数: |
264 次 |
| 最近记录: |