首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >这段代码来自“C++编程语言第4版”19.3.3.1节有效吗?

这段代码来自“C++编程语言第4版”19.3.3.1节有效吗?
EN

Stack Overflow用户
提问于 2018-07-17 16:44:14
回答 2查看 328关注 0票数 6

第19.3节在一章中给出了一个字符串表示,该章的主要焦点是操作符重载,特别是特殊运算符[]->()。它将copy_from()作为辅助功能实现,如下所示:

代码语言:javascript
复制
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;
    }
}

类接口如下所示:

代码语言:javascript
复制
#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有用户定义的构造函数、复制操作、移动操作和析构函数)。

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2018-07-17 18:52:01

String::copy_from()如何使用memcpy()复制类?

intchar和匿名联盟都是可以复制的。因此,虽然不能执行memcpyString,但可以执行其成员的memcpy。所有的一切都是一次。在技术上正确的代码是:

代码语言:javascript
复制
memcpy(&this->sz, &x.sz, sizeof(x));

标准布局类型的规则保证了复制此object.That成员的存储内存范围。对于标准布局类型,成员按定义顺序存储。因此,如果从第一个开始,并且覆盖所有对象的范围,那么应该复制成员。

但是,标准还规定,标准布局类型的第一个成员子对象必须具有与对象本身相同的地址:

如果标准布局类对象有任何非静态数据成员,则其地址与其第一个非静态数据成员的地址相同。

这意味着&this->sz必须是与this相同的地址,&x.sz必须是与&x相同的地址。

所以把中间的人剪掉吧:

代码语言:javascript
复制
memcpy(this, &x, sizeof(x));

这是允许的,因为标准布局类型的规则。

更大的问题是,copy_from从不检查自己的作业。memcpy不适用于重叠内存范围。也许operator=和类似的函数已经检查过了。

票数 5
EN

Stack Overflow用户

发布于 2018-07-17 16:51:37

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

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

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

代码语言:javascript
复制
if (x.sz <= short_max)
{
    sz = x.sz;
    ptr = ch;
    memcpy(&ch, &x.ch, sizeof(ch));
}
票数 -1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/51386532

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档