当前位置: 首页 > 知识库问答 >
问题:

“C编程语言第四版”第19.3.3.1节中的代码有效吗?

邢良才
2023-03-14

第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>具有用户定义的构造函数、复制操作、移动操作和析构函数)。


共有2个答案

微生景胜
2023-03-14

我认为你缺少的是代码正在显示一种称为短字符串优化的东西,它允许字符串存储在作为对象一部分的某个缓冲区内存中。

所以,是的,对于短字符串,整个类都可以被mem复制,因为这就是对象标识的全部内容。我不会这样做,但概念是对于短字符串,您可以逐个元素复制类的内容。(并重新分配ptr)。

我会这样做,避免讨论,我不认为效率低下。

if (x.sz <= short_max)
{
    sz = x.sz;
    ptr = ch;
    memcpy(&ch, &x.ch, sizeof(ch));
}
阙阳夏
2023-03-14
匿名用户

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语言与汇编之函数调用的本质