第19.3节介绍了一章中的字符串表示法,其主要重点是运算符重载,特别是特殊运算符[]、
、
-
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;
}
}
类接口如下所示:
#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()
复制类?我认为复制的类必须是可复制的(事实并非如此,因为<code>String</code>具有用户定义的构造函数、复制操作、移动操作和析构函数)。
我认为你缺少的是代码正在显示一种称为短字符串优化的东西,它允许字符串存储在作为对象一部分的某个缓冲区内存中。
所以,是的,对于短字符串,整个类都可以被mem复制,因为这就是对象标识的全部内容。我不会这样做,但概念是对于短字符串,您可以逐个元素复制类的内容。(并重新分配ptr
)。
我会这样做,避免讨论,我不认为效率低下。
if (x.sz <= short_max)
{
sz = x.sz;
ptr = ch;
memcpy(&ch, &x.ch, sizeof(ch));
}
匿名用户
String::copy_from()
如何使用 memcpy()
来复制类?
< code>int 、< code>char和匿名联合都很容易复制。因此,虽然不能对< code >字符串执行< code>memcpy,但可以对其成员执行< code>memcpy。所有人,一次全部。技术上正确的代码应该是:
memcpy(&this->sz, &x.sz, sizeof(x));
它为该对象的成员复制存储的内存范围。这是由标准布局类型的规则保证的。对于标准布局类型,成员按定义顺序存储。所以如果你从第一个开始,覆盖所有对象的范围,那就应该复制成员。
但是,标准还规定标准布局类型的第一个成员子对象必须与对象本身具有相同的地址:
如果标准布局类对象具有任何非静态数据成员,则其地址与第一个非静态数据构件的地址相同。
意思是<代码>
所以,只要去掉中间人:
memcpy(this, &x, sizeof(x));
这是因为标准布局类型的规则才允许的。
一个更大的问题是,copy_from从不检查自我分配。memcpy
不适用于重叠的内存范围。也许运算符=
和类似的函数已经检查过了。
在Bjarne Stroustrup的C编程语言第4版部分类似STL的操作中,以下代码被用作链接的示例: 断言在(实时查看)和(实时查看)中失败,但在使用Clang(实时查看)时不会失败。 为什么我得到了不同的结果?这些编译器中是否有任何一个错误地计算了链接表达式,或者这段代码是否表现出某种形式的未指定或未定义的行为?
这段代码的问题是变量不停留在2,它递增到3。您可以在此处查看:https://wandbox.org/permlink/p5JC1nOA4pIpsgXb 我们不必使用<code>std::ref()</code>来增加这个变量。这是书中的一个错误,还是自C 11以来发生了一些变化?
本文向大家介绍SQLite教程(十四):C语言编程实例代码(2),包括了SQLite教程(十四):C语言编程实例代码(2)的使用技巧和注意事项,需要的朋友参考一下 三、高效的批量数据插入: 在给出操作步骤之前先简单说明一下批量插入的概念,以帮助大家阅读其后的示例代码。事实上,批量插入并不是什么新的概念,在其它关系型数据库的C接口API中都提供了一定的支持,只是接口的实现方式不同而已。纵观众
第12章 汇编语言和C语言 C/C++语言是一个被广泛使用的程序设计语言,它不仅具有良好的高级语言特征,而且还具有一些低级语言的特点,如:寄存器变量、位操作等。所以,C语言的程序与汇编语言程序之间能很平滑地衔接。另外,目前主要的C语言程序开发环境,如:Turbo C/C++、Borland C/C++等,也都提供了很好的混合编程手段。 本章主要介绍汇编语言和C语言的混合编程和调用方法。虽然其它高级
1.字符串的扩展与修复 语言脚本都对字符串特别关注,有关的方法特别多,这些方法有三大类: 第一类:与标签无关的实现:charAt,charCodeAt,concat,lastIndexOf,localeCompare,match,replace,slice,split,substr,substring,toLocaleLowerCase,toLocalUpperCase,toLowerCase,t
C语言与汇编 汇编语言 C语言与汇编之计算机结构 C语言与汇编之用汇编写一个Helloword C语言与汇编之寄存器和寻址方式 C语言与汇编之函数调用的本质