首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >试图理解移动语义

试图理解移动语义
EN

Stack Overflow用户
提问于 2022-01-14 15:19:15
回答 1查看 84关注 0票数 1

我正在学习自C++11以来引入的“移动语义”,我编写了一个用普通构造函数、复制构造函数和移动构造函数创建类对象的示例代码。

代码语言:javascript
复制
/* Useless.cpp */
#include <iostream>

using namespace std;

// interface
class Useless {
private:
    int n; // number of elements
    char* pc; // pointer to data
    static int ct; // number of objects
    void ShowObject() const;
public:
    Useless();
    explicit Useless(int k);
    Useless(int k, char ch);
    Useless(const Useless & f); // regular copy constructor
    Useless(Useless && f); // move constructor
    ~Useless();

    Useless operator+(const Useless & f) const;
    void ShowData() const;
};

int Useless::ct = 0;

Useless::Useless() {
    ++ct;
    n = 0;
    pc =nullptr;
    cout << "default constructor called; number of objects" << ct << endl;
    ShowObject();
}

Useless::Useless(int k) : n(k) {
    ++ct;
    pc = new char[n];
    cout << "int constructor called; number of objects: " << ct << endl;
    ShowObject();
}

Useless::Useless(int k, char ch) : n(k) {
    ++ct;
    pc = new char[n];
    for (int i=0; i< n; i++) {
        pc[i] =  ch;
    }
    cout <<"int, char constructor called; number of objects: " << ct << endl;
    ShowObject();
}

Useless::Useless(const Useless & f) : n(f.n) {
    ++ct;
    pc = new char[n];

    for (int i =0; i< n; i++) {
        pc[i] = f.pc[i]; // deep copy 
    }
    cout << "copy const called; number of objects: " << ct << endl;
    ShowObject();
}

Useless::Useless(Useless && f) : n(f.n) {
    ++ct;
    pc = f.pc; // steal address (shallow copy)
    f.pc = nullptr;
    f.n = 0;
    cout << "move const called; number of objects: " << ct << endl;
    ShowObject();
}

Useless::~Useless() {
    cout << "destructor called; objects left: " << --ct << endl;
    cout << "deleted object:\n";
    ShowObject();
    delete [] pc;
}

Useless Useless::operator+(const Useless & f) const {
    cout << "Entering operator+() \n";
    Useless temp = Useless (n+f.n);

    for (int i=0; i < n; i++) {
        temp.pc[i] = pc[i]; // copy the current object's characters
    }

    for (int i=n; i < temp.n; i++) {
        temp.pc[i] = f.pc[i-n]; // copy the argument object's characters
    }
    cout << "temp object:\n";
    cout <<  "leaving operator+()\n"; 
    return temp;
}

void Useless::ShowObject() const {
    cout << "Number of elements: " << n; 
    cout << "Data address: " << (void *) pc << endl;
}

void Useless::ShowData() const {
    if (n==0) {
        cout << "(object empty)";
    }
    else {
        cout << "data: "; 

        for (int i = 0; i < n; i++) {
            cout << pc[i] ;
        }
    }
    cout << endl;
}

int main() {
    Useless one (10, 'x');
    Useless two = one; // call the copy constructor
    Useless three(20, 'o'); 
    Useless four(one+three); // it should call operator+() and then the move constructor

    cout << "object one: ";
    one.ShowData();
    cout << "object two: ";
    two.ShowData();
    cout << "object three: ";
    three.ShowData();
    cout << "object four: ";
    four.ShowData();
    return 0;
}

我期望代码生成五个Useless对象(即对象‘1’、‘2’3‘,这是由operator+()函数创建的临时对象,并将通过调用移动构造函数创建的对象’4‘)。然而,结果与我的预期不同。实际结果如下:

代码语言:javascript
复制
int, char constructor called; number of objects: 1
Number of elements: 10Data address: 0x56230b195eb0
copy const called; number of objects: 2
Number of elements: 10Data address: 0x56230b1962e0
int, char constructor called; number of objects: 3
Number of elements: 20Data address: 0x56230b196300
Entering operator+() 
int constructor called; number of objects: 4
Number of elements: 30Data address: 0x56230b196320
temp object:
**leaving operator+()**
object one: data: xxxxxxxxxx
object two: data: xxxxxxxxxx
object three: data: oooooooooooooooooooo
object four: data: xxxxxxxxxxoooooooooooooooooooo
destructor called; objects left: 3
deleted object:
Number of elements: 30Data address: 0x56230b196320
destructor called; objects left: 2
deleted object:
Number of elements: 20Data address: 0x56230b196300
destructor called; objects left: 1
deleted object:
Number of elements: 10Data address: 0x56230b1962e0
destructor called; objects left: 0
deleted object:
Number of elements: 10Data address: 0x56230b195eb0

我的期望是,程序通过调用上面定义的移动构造函数(以‘1+3’的结果作为输入参数)生成第五个对象(对象‘4’)。我希望有任何了解结果的线索。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2022-01-14 15:45:23

这就是复制省略和返回值优化的作用。见复制省略

在gcc/clang中,您可以使用-fno-elide-constructors禁用它,然后您将得到第5个对象。

票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/70712789

复制
相关文章

相似问题

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