微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

回推之间的 C++ 差异

如何解决回推之间的 C++ 差异

以下是具有不同类型回推的代码。我的意思是用不同的输入进行反击。一个例子是accounts.push_back(five)。我不确定为什么每种推回的构造函数打印输出都不同。不仅顺序不同,次数也不同,比如使用的深拷贝构造函数不同。

#include <iostream>
#include <vector>

class account
{
private:

    std::string *name_ptr;
    double *total_ptr;

public:
    
    std::string get_name() { return *name_ptr; }
    void set_name(std::string new_name) { *name_ptr = new_name; }
    
    double get_total() { return *total_ptr; }
    void set_total(double new_total) { *total_ptr = new_total; }
    
    void deposit(double amount) { *total_ptr += amount; }
    void withdraw(double amount) { *total_ptr -= amount; }

    account(std::string name,double total = 0)
    {
        name_ptr = new std::string {name};
        total_ptr = new double {total};
        std::cout << "Constructor for " << *name_ptr << std::endl;
    }
    
    account(const account &source)
    : account {*(source.name_ptr),*(source.total_ptr)}
    { std::cout << "Deep copy constructor for " << *name_ptr << std::endl; }
    
    account(account &&source) noexcept
    : name_ptr(source.name_ptr),total_ptr(source.total_ptr)
    {
        source.name_ptr = nullptr;
        source.total_ptr = nullptr;
        std::cout << "Move constructor for " << *name_ptr << std::endl;
    }
    
    ~account()
    {
        if(name_ptr == nullptr) std::cout << "Destructor for nullptr" << std::endl;
        else std::cout << "Destructor for " << *name_ptr << std::endl;
        delete name_ptr;
        delete total_ptr;
    }

};

int main()
{
    std::vector<account> accounts;
    
    account one {"Jonathon Stevenson"};
    accounts.push_back( account(one) );
    account two {"Cliffard Stevenson"};
    accounts.push_back( account(two) );
    account three {"Tom Stevenson"};
    accounts.push_back( account(three) );
    std::cout << std::endl;
    
    account four {"Jonathon Richardson"};
    accounts.push_back(four);
    account five {"Cliffard Richardson"};
    accounts.push_back(five);
    account six {"Tom Richardson"};
    accounts.push_back(six);
    std::cout << std::endl;
    
    accounts.push_back( account {"Jonathon Watson"} );
    accounts.push_back( account {"Cliffard Watson"} );
    accounts.push_back( account {"Tom Watson"} );
    std::cout << std::endl;
    
    accounts.push_back( account("Jonathon Sullivanson") );
    accounts.push_back( account("Cliffard Sullivanson") );
    accounts.push_back( account("Tom Sullivanson") );
    std::cout << std::endl;

    return 0;
}

输出

Constructor for Jonathon Stevenson
Constructor for Jonathon Stevenson
Deep copy constructor for Jonathon Stevenson
Move constructor for Jonathon Stevenson
Destructor for nullptr
Constructor for Cliffard Stevenson
Constructor for Cliffard Stevenson
Deep copy constructor for Cliffard Stevenson
Move constructor for Cliffard Stevenson
Move constructor for Jonathon Stevenson
Destructor for nullptr
Destructor for nullptr
Constructor for Tom Stevenson
Constructor for Tom Stevenson
Deep copy constructor for Tom Stevenson
Move constructor for Tom Stevenson
Move constructor for Jonathon Stevenson
Move constructor for Cliffard Stevenson
Destructor for nullptr
Destructor for nullptr
Destructor for nullptr

Constructor for Jonathon Richardson
Constructor for Jonathon Richardson
Deep copy constructor for Jonathon Richardson
Constructor for Cliffard Richardson
Constructor for Cliffard Richardson
Deep copy constructor for Cliffard Richardson
Move constructor for Jonathon Stevenson
Move constructor for Cliffard Stevenson
Move constructor for Tom Stevenson
Move constructor for Jonathon Richardson
Destructor for nullptr
Destructor for nullptr
Destructor for nullptr
Destructor for nullptr
Constructor for Tom Richardson
Constructor for Tom Richardson
Deep copy constructor for Tom Richardson

Constructor for Jonathon Watson
Move constructor for Jonathon Watson
Destructor for nullptr
Constructor for Cliffard Watson
Move constructor for Cliffard Watson
Destructor for nullptr
Constructor for Tom Watson
Move constructor for Tom Watson
Move constructor for Jonathon Stevenson
Move constructor for Cliffard Stevenson
Move constructor for Tom Stevenson
Move constructor for Jonathon Richardson
Move constructor for Cliffard Richardson
Move constructor for Tom Richardson
Move constructor for Jonathon Watson
Move constructor for Cliffard Watson
Destructor for nullptr
Destructor for nullptr
Destructor for nullptr
Destructor for nullptr
Destructor for nullptr
Destructor for nullptr
Destructor for nullptr
Destructor for nullptr
Destructor for nullptr

Constructor for Jonathon Sullivanson
Move constructor for Jonathon Sullivanson
Destructor for nullptr
Constructor for Cliffard Sullivanson
Move constructor for Cliffard Sullivanson
Destructor for nullptr
Constructor for Tom Sullivanson
Move constructor for Tom Sullivanson
Destructor for nullptr

Destructor for Tom Richardson
Destructor for Cliffard Richardson
Destructor for Jonathon Richardson
Destructor for Tom Stevenson
Destructor for Cliffard Stevenson
Destructor for Jonathon Stevenson
Destructor for Jonathon Stevenson
Destructor for Cliffard Stevenson
Destructor for Tom Stevenson
Destructor for Jonathon Richardson
Destructor for Cliffard Richardson
Destructor for Tom Richardson
Destructor for Jonathon Watson
Destructor for Cliffard Watson
Destructor for Tom Watson
Destructor for Jonathon Sullivanson
Destructor for Cliffard Sullivanson
Destructor for Tom Sullivanson

解决方法

这就是 std::vector 的工作原理。

每当内存不足时,在下一个 std::vector::push_back 时,它只会分配一个新块,复制(或移动,如果可能)所有数据,然后删除旧数据。由于它无法真正知道您需要多少空间,因此自动重新分配依赖于某种策略,其中最常见的是分配 N * 2,其中 N 是当前容量。现在让我们看看 main 中发生了什么。

std::vector<account> accounts; - 这会创建一个空向量(无分配)。

account one {"Jonathon Stevenson"}; - 这通过调用您的类创建一个对象,我们称之为字符串构造函数,这是您将第一个输出输入到控制台的地方。

accounts.push_back(account(one)); - 这一条负责接下来的三个消息(account(one) 使用复制构造函数创建一个临时的,它通过调用字符串构造函数来工作;之后,所述临时被移动到向量中) .这里accounts的容量为1;

创建和推送的下一个“迭代”以相同的方式工作,除了您有一个额外的移动:即 vector 将数据移动到新位置。这里accounts的容量是2;

同样适用于下一个。这里accounts的容量是4;

然后,在 accounts.push_back(four); - 您不再创建过多的临时文件,因此看不到移动构造函数的工作。这里accounts的容量是4;

在下一个 push_back 发生另一次重新分配,您可以看到 vector 将所有内容(4 个元素)移动到新位置。

最后,当您尝试 accounts.push_back( account("Tom Sullivanson") ); 时,您的容量为 8,而 accounts 中的元素数也是 8,因此您可以看到 vector 再次将其内容移动到新位置 - 正好 8 次。现在容量为 16,并且此程序中不会再发生重新分配。

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐


Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其他元素将获得点击?
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。)
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbcDriver发生异常。为什么?
这是用Java进行XML解析的最佳库。
Java的PriorityQueue的内置迭代器不会以任何特定顺序遍历数据结构。为什么?
如何在Java中聆听按键时移动图像。
Java“Program to an interface”。这是什么意思?