本文主要是介绍移动构造函数是否标记noexcept对性能有重要影响,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!
1. 移动构造标记noexcept
时才会被正确调用
#include <iostream>
#include <string>
#include <vector>class Vehicle{
public:Vehicle(){std::cout << "Vehicle default-ctor called.\n";}Vehicle(const std::string& brand) : brand_(brand) {std::cout << "Vehicle ctor called.\n";}virtual ~Vehicle(){std::cout << "Vehicle dtor called.\n";}Vehicle(const Vehicle& rhs) : brand_(rhs.brand_) {std::cout << __PRETTY_FUNCTION__ << std::endl;}Vehicle& operator=(const Vehicle& rhs) &{Vehicle(rhs).swap(*this);std::cout << __PRETTY_FUNCTION__ << std::endl;return *this;}void swap(Vehicle& rhs) noexcept {brand_.swap(rhs.brand_);}Vehicle(Vehicle&& rhs) noexcept: brand_(rhs.brand_) {std::cout << __PRETTY_FUNCTION__ << std::endl;}Vehicle& operator=(Vehicle&& rhs) & noexcept {brand_ = rhs.brand_;std::cout << __PRETTY_FUNCTION__ << std::endl;return *this;}private:std::string brand_;
};Vehicle getVehicle(){return Vehicle("Tesla");
}int main() {// 调用getVehicle()时仅会调用一次构造函数,并没有调用移动赋值运算符,这是因为存在返回值优化// 所以函数可以直接返回对象,不需要通过出参的方式Vehicle vec1 = getVehicle(); // Vehicle ctor called.Vehicle vec2("BYD"); // Vehicle ctor called.std::cout << std::string(40, '-') << std::endl;vec2 = getVehicle(); // Vehicle ctor called.// Vehicle& Vehicle::operator=(Vehicle&&) &// Vehicle dtor called.std::cout << std::string(40, '-') << std::endl;Vehicle vec3(std::move(vec1)); // Vehicle::Vehicle(Vehicle&&)std::cout << std::string(40, '-') << std::endl;std::vector<Vehicle> vecs1(4, Vehicle("LINKO")); // Vehicle ctor called.// Vehicle::Vehicle(const Vehicle&)// Vehicle::Vehicle(const Vehicle&)// Vehicle::Vehicle(const Vehicle&)// Vehicle::Vehicle(const Vehicle&)// Vehicle dtor called.std::cout << std::string(40, '-') << std::endl;std::vector<Vehicle> vecs2(4); // Vehicle default-ctor called.// Vehicle default-ctor called.// Vehicle default-ctor called.// Vehicle default-ctor called.std::cout << std::string(40, '-') << std::endl;vecs2.emplace_back(); // Vehicle default-ctor called.// Vehicle::Vehicle(Vehicle&&)// Vehicle dtor called.// Vehicle::Vehicle(Vehicle&&)// Vehicle dtor called.// Vehicle::Vehicle(Vehicle&&)// Vehicle dtor called.// Vehicle::Vehicle(Vehicle&&)// Vehicle dtor called.std::cout << std::string(40, '-') << std::endl;vecs2.emplace_back(); // Vehicle default-ctor called.std::cout << std::string(40, '-') << std::endl;vecs2.push_back(Vehicle()); // Vehicle default-ctor called.// Vehicle::Vehicle(Vehicle&&)// Vehicle dtor called.std::cout << std::string(40, '-') << std::endl;
}
输出:
Vehicle ctor called.
Vehicle ctor called.
----------------------------------------
Vehicle ctor called.
Vehicle& Vehicle::operator=(Vehicle&&) &
Vehicle dtor called.
----------------------------------------
Vehicle::Vehicle(Vehicle&&)
----------------------------------------
Vehicle ctor called.
Vehicle::Vehicle(const Vehicle&)
Vehicle::Vehicle(const Vehicle&)
Vehicle::Vehicle(const Vehicle&)
Vehicle::Vehicle(const Vehicle&)
Vehicle dtor called.
----------------------------------------
Vehicle default-ctor called.
Vehicle default-ctor called.
Vehicle default-ctor called.
Vehicle default-ctor called.
----------------------------------------
Vehicle default-ctor called.
Vehicle::Vehicle(Vehicle&&)
Vehicle dtor called.
Vehicle::Vehicle(Vehicle&&)
Vehicle dtor called.
Vehicle::Vehicle(Vehicle&&)
Vehicle dtor called.
Vehicle::Vehicle(Vehicle&&)
Vehicle dtor called.
----------------------------------------
Vehicle default-ctor called.
----------------------------------------
Vehicle default-ctor called.
Vehicle::Vehicle(Vehicle&&)
Vehicle dtor called.
----------------------------------------
Vehicle dtor called.
Vehicle dtor called.
Vehicle dtor called.
Vehicle dtor called.
Vehicle dtor called.
Vehicle dtor called.
Vehicle dtor called.
Vehicle dtor called.
Vehicle dtor called.
Vehicle dtor called.
Vehicle dtor called.
Vehicle dtor called.
Vehicle dtor called.
Vehicle dtor called.
2. 当移动构造未标记noexcept
时该调用移动构造的时候可能调用的是拷贝构造
#include <iostream>
#include <string>
#include <vector>class Vehicle{
public:Vehicle(){std::cout << "Vehicle default-ctor called.\n";}Vehicle(const std::string& brand) : brand_(brand) {std::cout << "Vehicle ctor called.\n";}virtual ~Vehicle(){std::cout << "Vehicle dtor called.\n";}Vehicle(const Vehicle& rhs) : brand_(rhs.brand_) {std::cout << __PRETTY_FUNCTION__ << std::endl;}Vehicle& operator=(const Vehicle& rhs) &{Vehicle(rhs).swap(*this);std::cout << __PRETTY_FUNCTION__ << std::endl;return *this;}void swap(Vehicle& rhs) noexcept {brand_.swap(rhs.brand_);}Vehicle(Vehicle&& rhs) /*noexcept*/: brand_(rhs.brand_) {std::cout << __PRETTY_FUNCTION__ << std::endl;}Vehicle& operator=(Vehicle&& rhs) & noexcept {brand_ = rhs.brand_;std::cout << __PRETTY_FUNCTION__ << std::endl;return *this;}private:std::string brand_;
};Vehicle getVehicle(){return Vehicle("Tesla");
}int main() {// 调用getVehicle()时仅会调用一次构造函数,并没有调用移动赋值运算符,这是因为存在返回值优化// 所以函数可以直接返回对象,不需要通过出参的方式Vehicle vec1 = getVehicle(); // Vehicle ctor called.Vehicle vec2("BYD"); // Vehicle ctor called.std::cout << std::string(40, '-') << std::endl;vec2 = getVehicle(); // Vehicle ctor called.// Vehicle& Vehicle::operator=(Vehicle&&) &// Vehicle dtor called.std::cout << std::string(40, '-') << std::endl;Vehicle vec3(std::move(vec1)); // Vehicle::Vehicle(Vehicle&&)std::cout << std::string(40, '-') << std::endl;std::vector<Vehicle> vecs1(4, Vehicle("LINKO")); // Vehicle ctor called.// Vehicle::Vehicle(const Vehicle&)// Vehicle::Vehicle(const Vehicle&)// Vehicle::Vehicle(const Vehicle&)// Vehicle::Vehicle(const Vehicle&)// Vehicle dtor called.std::cout << std::string(40, '-') << std::endl;std::vector<Vehicle> vecs2(4); // Vehicle default-ctor called.// Vehicle default-ctor called.// Vehicle default-ctor called.// Vehicle default-ctor called.std::cout << std::string(40, '-') << std::endl;vecs2.emplace_back(); // Vehicle default-ctor called.// Vehicle::Vehicle(const Vehicle&)// Vehicle::Vehicle(const Vehicle&)// Vehicle::Vehicle(const Vehicle&)// Vehicle::Vehicle(const Vehicle&)// Vehicle dtor called.// Vehicle dtor called.// Vehicle dtor called.// Vehicle dtor called.std::cout << std::string(40, '-') << std::endl;vecs2.emplace_back(); // Vehicle default-ctor called.std::cout << std::string(40, '-') << std::endl;vecs2.push_back(Vehicle()); // Vehicle default-ctor called.// Vehicle::Vehicle(Vehicle&&)// Vehicle dtor called.std::cout << std::string(40, '-') << std::endl;
}
输出结果:
Vehicle ctor called.
Vehicle ctor called.
----------------------------------------
Vehicle ctor called.
Vehicle& Vehicle::operator=(Vehicle&&) &
Vehicle dtor called.
----------------------------------------
Vehicle::Vehicle(Vehicle&&)
----------------------------------------
Vehicle ctor called.
Vehicle::Vehicle(const Vehicle&)
Vehicle::Vehicle(const Vehicle&)
Vehicle::Vehicle(const Vehicle&)
Vehicle::Vehicle(const Vehicle&)
Vehicle dtor called.
----------------------------------------
Vehicle default-ctor called.
Vehicle default-ctor called.
Vehicle default-ctor called.
Vehicle default-ctor called.
----------------------------------------
Vehicle default-ctor called.
Vehicle::Vehicle(const Vehicle&)
Vehicle::Vehicle(const Vehicle&)
Vehicle::Vehicle(const Vehicle&)
Vehicle::Vehicle(const Vehicle&)
Vehicle dtor called.
Vehicle dtor called.
Vehicle dtor called.
Vehicle dtor called.
----------------------------------------
Vehicle default-ctor called.
----------------------------------------
Vehicle default-ctor called.
Vehicle::Vehicle(Vehicle&&)
Vehicle dtor called.
----------------------------------------
Vehicle dtor called.
Vehicle dtor called.
Vehicle dtor called.
Vehicle dtor called.
Vehicle dtor called.
Vehicle dtor called.
Vehicle dtor called.
Vehicle dtor called.
Vehicle dtor called.
Vehicle dtor called.
Vehicle dtor called.
Vehicle dtor called.
Vehicle dtor called.
Vehicle dtor called.
这篇关于移动构造函数是否标记noexcept对性能有重要影响的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!