我想在编译器通常自动生成默认构造函数,复制构造函数和赋值运算符的条件下刷新内存.
我记得有一些规则,但我不记得了,也无法在网上找到有信誉的资源.有人可以帮忙吗?
c++ copy-constructor default-constructor move-constructor move-assignment-operator
这是
struct Example {
int a, b;
Example(int mA, int mB) : a{mA}, b{mB} { }
Example(const Example& mE) : a{mE.a}, b{mE.b} { }
Example(Example&& mE) : a{move(mE.a)}, b{move(mE.b)} { }
Example& operator=(const Example& mE) { a = mE.a; b = mE.b; return *this; }
Example& operator=(Example&& mE) { a = move(mE.a); b = move(mE.b); return *this; }
}
Run Code Online (Sandbox Code Playgroud)
相当于此
struct Example {
int a, b;
Example(int mA, int mB) : a{mA}, b{mB} { }
Example(const Example& mE) = default; …Run Code Online (Sandbox Code Playgroud) 为什么C++编译器对自动生成的移动构造函数的限制比对自动生成的复制构造函数或赋值运算符的限制更多?
仅当用户没有定义任何内容时才会生成自动生成的移动构造函数(即:构造函数,复制,赋值,析构函数..)
仅当用户未分别定义复制构造函数或赋值运算符时,才会生成复制构造函数或赋值运算符.
我想知道为什么不同.
我喜欢const成员变量的想法,特别是当我将C函数包装到类中时.构造函数获取在整个对象生命周期内保持有效的资源句柄(例如文件描述符),析构函数最终将其关闭.(那是RAII背后的想法,对吧?)
但是使用C++ 0x移动构造函数我遇到了问题.由于析构函数也在"卸载"对象上调用,我需要防止资源句柄的清理.由于成员变量是const,我无法分配值-1或INVALID_HANDLE(或等效值)来向析构函数指示它不应该执行任何操作.
有没有办法在对象的状态被移动到另一个对象时不调用析构函数?
例:
class File
{
public:
// Kind of "named constructor" or "static factory method"
static File open(const char *fileName, const char *modes)
{
FILE *handle = fopen(fileName, modes);
return File(handle);
}
private:
FILE * const handle;
public:
File(FILE *handle) : handle(handle)
{
}
~File()
{
fclose(handle);
}
File(File &&other) : handle(other.handle)
{
// The compiler should not call the destructor of the "other"
// object.
}
File(const File &other) = delete;
File &operator =(const File &other) …Run Code Online (Sandbox Code Playgroud) 我问了一个关于移动构造函数的问题,我尚未接受答案,因为即使我开始掌握其他问题,我对问题的某些方面感到更加困惑.特别是,我发现了一个令人惊讶的案例,其中g ++和clang ++都生成了错误的移动构造函数.
delete函数.Qt库(版本5.4)是否这样做?请考虑以下代码:
class NoMove
{
public:
~NoMove() {}
};
int main()
{
std::cout << "NoMove move-constructible? " <<
std::is_move_constructible<NoMove>::value << std::endl;
}
Run Code Online (Sandbox Code Playgroud)
使用g++4.9.2和clang++3.5.1 编译,此代码打印:
NoMove move-constructible? 1
Run Code Online (Sandbox Code Playgroud)
...但是由于NoMove有一个明确定义的析构函数,我希望不应该自动生成移动构造函数和复制构造函数.请注意,意外的构造函数生成不是因为析构函数是微不足道的; 当析构函数delete[]是一个数组(!!)时,我得到了相同的行为,我甚至能够编译需要有效移动构造函数的代码(!!!!!).(见下面的例子.)这里发生了什么?在这里自动生成移动构造函数是否合法,如果是,为什么?
看来,提供安全的移动构造函数时delete涉及相当简单,但我只是想确保我的理解:当一个类包含一个指向成员,拥有基本数据,有没有任何在它是不正确和案例在将目标指针设置为旧值后,移动构造函数是否足以使RHS指针无效?
请考虑以下示例,该NoMove示例与上面的示例类似,并基于我原来的问题:
class DataType
{
public:
DataType()
{
val …Run Code Online (Sandbox Code Playgroud) 以下不会编译(尝试过clang和gcc)
#include <vector>
struct Foo
{
Foo(int a=0) : m_a(a) {}
Foo(const Foo& f) = delete;
// Foo(Foo&& f) = default;
private:
int m_a;
};
int main()
{
std::vector<Foo> foovec;
foovec.emplace_back(44); // might resize, so might move
}
Run Code Online (Sandbox Code Playgroud)
但是如果我不删除复制构造函数,或者如果我默认移动构造函数,
它将起作用.因此,没有删除拷贝构造函数抑制移动构造函数,
并且什么是背后的理性?
我做了一个程序来评估这样做之间的性能差异:
func3(func2(func1()));
Run Code Online (Sandbox Code Playgroud)
对此:
retval1 = func1();
retval2 = func2(retval1);
func3(retval2);
Run Code Online (Sandbox Code Playgroud)
我更喜欢后者的可读性和易于调试,我想知道编译器(MSVC 12.0)是否会优化发布版本中的中间对象.我的测试程序是这样的:
#include <iostream>
using namespace std;
struct Indicator {
Indicator() {cout << "Default constructor" << endl;}
Indicator(const Indicator& other) {cout << "Copy constructor" << endl;}
const Indicator& operator=(const Indicator& other) {cout << "Assignment operator" << endl;}
~Indicator() {cout << "Destructor" << endl;}
};
Indicator func1()
{return Indicator();}
Indicator func2(Indicator&& i)
{return std::move(i);}
Indicator func3(Indicator&& i)
{return std::move(i);}
int main() {
Indicator i = func3(func2(func1()));
cout << &i << endl; …Run Code Online (Sandbox Code Playgroud) 我有一个结构列表,我正在由其中一个成员排序.我正在使用std :: sort和我自己的比较函数,那部分很好.但是,当我从以下位置更改结构时,我注意到(非常)大的性能差距:
struct square
{
float x;
float y;
float z;
float scale;
float angle;
GLuint texture;
};
Run Code Online (Sandbox Code Playgroud)
至
struct square
{
float x;
float y;
float z;
float scale;
float angle;
GLuint texture;
std::vector <float> color;
};
Run Code Online (Sandbox Code Playgroud)
我已经使用了一种完全不同的方法,我意识到使用这样的矢量是一个坏主意(我知道数组的大小 - rgb),但我想知道为什么我的性能受到了影响.我正在比较z值以进行排序.
这是我的排序函数和结构列表:
std::vector <square> square_list;
//Then add a bunch of squares
bool sort (square a,square b)
{
return a.z < b.z;
}
//Here is the sort that is slow
std::sort (square_list.begin(),square_list.end(),sort);
Run Code Online (Sandbox Code Playgroud)
我想知道它是否与重新排序结构列表有关,因为它们的大小在第二种情况下要大得多?
感谢您的回复.