C++ 返回值优化和返回复杂类问题

c++ return value optimization and returning complex class problem

提问人:Osman 提问时间:9/24/2022 更新时间:9/24/2022 访问量:75

问:

根据这个问题和答案,当我们从函数返回一个对象时,它取决于编译器和 c++ 版本如何返回,它可以被移动、复制或省略。
想象一下我有复杂的类,例如(可能更复杂)


class Basket{
    public:
        Basket (); // ctor 
        ~Basket (); // dtor
        Basket (Basket &); // copy ctor
        Basket (Basket &&); // move ctor
        Basket & operator= (Basket &); // copy assignment
        Basket & operator= (Basket &&); // move assignment
        // getter setters
    private:
        vector<Products> product_list;
        vector<Liked> liked_list;
}

class Customer
{               // Note: All methods have side effects
  public: 
  
    Customer (); // ctor 
    ~ Customer (); // dtor
    Customer (Customer &); // copy ctor
    Customer (Customer &&); // move ctor
    Customer & operator= (Customer &); // copy assignment
    Customer & operator= (Customer &&); // move assignment
    // getter setters
    
  private:
    vector<int*> some_ptrs;
    vector<Adress> adress_list;
    CustomerInfo customer_info;
    vector<Basket> basket;
};

Customer get_customer(int id) {
    Customer customer = db.get_customer(id);
    return customer;
}

如果我的复制和移动语义有副作用,并且不清楚使用哪种方法,我该如何编写一致且高效的代码?
有哪些最佳实践可以确保我的代码按预期和高效工作,而不管使用的 c++ 的实现和版本如何。

C++ 复制构造函数 move-semantics

评论

0赞 Some programmer dude 9/24/2022
为什么你有类的复制和移动语义?为什么类中有一个指针向量?它是数组的向量吗?然后改用向量的向量。如果去掉指针,则也可以跳过类的复制和移动操作。BasketintCustomerCustomer
0赞 Some programmer dude 9/24/2022
此外,该函数可以简化为简单,这肯定会调用 RVO(尽管希望启用优化的编译器无论如何都可以这样做)。get_customerreturn db.get_customer(id);
0赞 HolyBlackCat 9/24/2022
链接的 Q&A 表示对象将被移动一两次,永远不会复制。(除非您使用 C++98。
0赞 HolyBlackCat 9/24/2022
类不应具有自定义析构函数以及复制和移动操作。这些是一个相当先进的工具,您不需要经常使用。如果您使用它们为它们动态分配内存,请将它们替换为容器或智能指针。但是,如果您确实需要自定义复制和移动操作,则复制操作应接受 const refs,而移动操作应为 noexcept。int*
0赞 Osman 9/24/2022
@Someprogrammerdude我知道你说的所有事情,但我在这里说的是假设性的。语言允许我做这些,所以我只是做了:)

答: 暂无答案