析构函数
构造函数是把对象构造出来,析构函数就是把对象销毁掉。 但是注意内存的分配与释放,和构造函数与析构函数无关。
#include <iostream>
#include <string>
#include <vector>
using namespace std;
struct Str
{
Str()
{
cout << "Constructor is called" << endl;
}
~Str()
{
cout << "Destructor is called" << endl;
}
int val = 3;
std::string a = "abc";
int* ptr;
};
int main()
{
Str m;
Str m2;
Str m3;
Str* m_ptr = new Str();
delete m_ptr;
}
除非显式声明,否则编译器自动合成。 上面这句话不写,就是自动合成。 析构函数通常不能抛出异常。因为析构函数是销毁对象,一般都会被调用,如果也抛出异常,那么程序中本来有的异常就可能被隐藏。这不是我们想看到的。
#include <iostream>
#include <string>
#include <vector>
using namespace std;
class Str
{
public:
Str() :ptr(new int()) {}
~Str() {delete ptr; }
Str(const Str& val)
: ptr(new int())
{
*ptr = *(val.ptr);
}
Str(Str&& val)
: ptr(val.ptr)
{
val.ptr = nullptr;
}
Str& operator= (const Str& val)
{
*ptr = *(val.ptr);
return *this;
}
int& Data()
{
return *ptr;
}
private:
int* ptr;
};
int main()
{
Str a;
a.Data() = 3;
cout << a.Data() << endl;
Str b(a);
b = a;
Str c = std::move(a);
}
delete关键字
default 关键字 ,只对特殊成员函数有效。但是,delete对所有的函数都有效。 通常来讲,我们会给析构函数加delete。delete就是不让析构。构造函数一般可以加delete,就是不让构造。
#include <iostream>
#include <string>
#include <vector>
using namespace std;
class Str
{
public:
Str() :ptr(new int()) {}
~Str() = delete;
Str(const Str& val)
: ptr(new int())
{
*ptr = *(val.ptr);
}
Str(Str&& val)
: ptr(val.ptr)
{
val.ptr = nullptr;
}
Str& operator= (const Str& val)
{
*ptr = *(val.ptr);
return *this;
}
int& Data()
{
return *ptr;
}
private:
int* ptr;
};
int main()
{
Str a;
a.Data() = 3;
cout << a.Data() << endl;
Str b(a);
b = a;
Str c = std::move(a);
}
通常不要给移动构造和移动赋值引入delete限定符。 如果只需要拷贝行为,那么引入拷贝构造和拷贝赋值即可。 如果不需要拷贝行为,那么拷贝构造和拷贝赋值只需要一个声明+delete限定符即可。 不要为移动构造或者移动赋值引入delete。
字面值类
可以构造编译期的抽象数据类型。
#include <iostream>
#include <string>
#include <vector>
using namespace std;
class Str
{
public:
constexpr Str(int val)
: x(val)
{
}
private:
int x;
};
int main()
{
constexpr Str a(100);
}
字面值类是比较特殊的数据结构,可以在编译期使用。但是使用的范围比较窄。
成员指针
#include <iostream>
#include <string>
#include <vector>
using namespace std;
class Str
{
public:
int x;
};
int main()
{
int Str::*ptr;
void (Str::* ptr_fun) ();
int Str::* ptr1 = &Str::x;
}
bind交互
|