gpt4 book ai didi

c++ - 减少复制构造函数调用

转载 作者:搜寻专家 更新时间:2023-10-31 02:05:25 24 4
gpt4 key购买 nike

以下代码是我正在处理的项目中的一个最小示例。主要问题是我想减少对复制构造函数的调用次数,但我不清楚这样做的正确方法。

#include<iostream>

class MyClass
{
public:
MyClass() {std::cout << "Default Constructor\n";}
MyClass(const MyClass &input) {std::cout << "Copy Constructor\n";}
MyClass & operator=(const MyClass &input)
{std::cout << "Assignment\n"; return *this;}
MyClass & operator+=(const MyClass &input) {return *this;}
friend MyClass operator+(MyClass lhs,const MyClass &);
};

MyClass operator+(MyClass lhs,const MyClass &rhs)
{lhs+=rhs;return lhs;}

int main()
{
MyClass a,b,c;
c=a+b;
return 0;
}

当我运行代码时,输​​出是:

Default Constructor
Default Constructor
Default Constructor
Copy Constructor
Copy Constructor
Assignment
  • 在构造a、b、c时调用了三个默认构造函数。

  • 为 operator+ 中的第一个参数和 operator+ 的返回调用两个复制构造函数。

  • 赋值是将a+b赋值给c的结果。

主要问题:在我的应用程序中,复制构造函数是昂贵的(它涉及内存分配)。另一方面,分配相对便宜。减少对复制构造函数的调用的正确方法是什么?

我考虑过一些解决方案,但没有一个让我满意:

  • 据我了解,从阅读中可以看出,operator+ 不应为第一个参数提供引用,因为这有助于链接临时变量。因此,这个拷贝构造函数似乎是不可避免的。

  • 以下代码明显更快(由于没有复制构造函数调用):c = a; c += b; 我可以使用这种格式编写代码,但这需要更精细的方法。我希望编译器更智能,而不是让我自己进行这些调整。

  • 我可以实现一个函数 add(MyClass &,const MyClass &,const MyClass &); 但这失去了使用加法运算符的便利性(并且需要大量(无意识的) 由于我使用的不同数据类型的数量而编码)。

  • 我查看了这些问题,但我没有看到任何可能在这种情况下提高性能的建议:

Copy constructor called twice , Copy constructor called twice , 和 Conditions for copy elision

评论回复:

  • 私有(private)数据包括 MPFR 和 MPFI,构造函数包括此数据的初始化。也许构造函数的不同实现是合适的,但我不确定。

  • 我考虑过移动构造函数,但有时我也想要复制复制赋值。来自 cppreference看起来这些不能共存(或者至少我一开始尝试时出错)。看来这应该是最好的选择。

最佳答案

为了尽量减少复制构造函数调用,我建议您定义移动构造函数并完美转发您的运算符参数。移动构造函数:

MyClass(MyClass &&input) {std::cout << "Move Constructor\n";}

完美转发操作符:

template<typename T>
friend MyClass operator+(T &&lhs,T &&rhs) {return std::forward<T>(lhs);}

通过正确的调用,您的运算符将涉及移动构造函数而不是复制构造函数。例如,如果您添加来自函数的对象并立即存储结果(例如 MyClass c=a+b; 而不是 MyClass c;c=a+b;),感谢 RVO您可以保存复制构造函数。

假设您有一个返回 MyClass 实例的函数:

MyClass something() {return MyClass();}

如果添加函数返回值并立即存储它们,例如:

MyClass c=something()+something();

那么就不会涉及复制构造函数。

我已经放了一系列例子here其中我将 const MyClass& 参数与 operator+ 一起使用,并将完美转发参数与 operator- 一起使用。您可以看到它在最后一个示例中有所不同,但在所有其他示例中都没有。这就是为什么我说“用正确的电话”。如果您必须像那样操作可以转发的对象,那么值得一试。

关于c++ - 减少复制构造函数调用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52043470/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com