19
- 当我们想要自定义 operator new 函数,可以为他提供额外的形参。用到这些自定义函数的new表达式必须使用new的定位形式。
void *operator new(size_t size, const char *filename, int line) {
void *ptr = new char[size];
cout << "size = " << size << " filename = " << filename << " line = " << line
<< endl;
return ptr;
}
int main() { int *x = new(__FILE__, __LINE__) int; }
- new operator 和 new expression 的含义区别:
-
https://stackoverflow.com/questions/31106449/why-overloaded-new-operator-is-calling-constructor-even-i-am-using-malloc-inside
-
A new expression results in two separate things happening: allocation of the memory needed by the object begin created, and initialization of the object.
-
The new operator, on the other hand, just handles the allocation part. When you overload the new operator with respect to a specific class, you are replacing the allocation of memory to the object.
- 所以 overload 只会处理 new operator,也就是资源分配的行为
-
-
不能定义
void operator new(size_t, void *)的 overload 函数,因为这是给标准库使用的 - 当 delete 是成员函数的时候:
- delete 和 new 都是 implict static 的,所以,一般都是 base class 定义
- delete 可以定义另外一个参数 size_t,其数值取决于动态类型
- deconstructor 函数也是递归调用的,而且需要配合上 virtual 才可以完全符合我们的设想 ```cpp class A { public: void operator delete(void * ptr, size_t size){ cout « size « ” deleted” « endl; } ~A() { cout « “A” « endl; } };
class B : public A { int a[100]; public: ~B() { cout « “B” « endl; } };
int main() { A *a = new B; delete a;
cout « ”———” « endl;
B *b = new B; delete b; }
5. placement new 和 explicit 调用 deconstructor 的含义:
- https://stackoverflow.com/questions/3763846/what-is-an-in-place-constructor-in-c
- https://stackoverflow.com/questions/35087204/how-c-placement-new-works
- 给出了几个小例子, 很容易理解
- 那就是 : 对象的构造 和 对象的空间的释放是可以分开的
6. 通过 typeid 和 dynamic_cast 实现 RTTI
7. reference type 的 dynamic_cast 必须使用 try catch 来捕获的原因:
- https://stackoverflow.com/questions/1276847/difference-in-behavior-while-using-dynamic-cast-with-reference-and-pointers
- 简而言之: 指针类型出错,可以靠 nullptr, 但是 reference 类型没有 nullref 的操作
8. 当 typeid 作用于指针时,返回的结果是该指针的静态编译类型
9. 当指针 p 指向的类不含有 虚函数的时候,则 p 不需要是 valid 的指针。这是因为一个是静态求值的,而一个动态求值的。
- [ ] 说实话,这很奇怪,但是这牵涉到 : move
- https://stackoverflow.com/questions/3601602/what-are-rvalues-lvalues-xvalues-glvalues-and-prvalues
- https://en.cppreference.com/w/cpp/language/value_category
```cpp
class A {
// 是否定义这一句的含义完全不同 !
virtual void fuck() {}
};
class B : public A {};
int main(int argc, char *argv[]) {
B *b = new B;
A *a = b;
if (typeid(*a) == typeid(*b)) {
cout << "impossible\n";
}
return 0;
}
- 使用 RTTI 在实现 equal 函数非常方便
- 首先比较 RTTI 保证 lhs 和 rhs 类型
- 定义 virtual equal(const Base & b), 在 base 中间,这个函数的权限是 protected
- 最后定义 operator ==
-
通过 typeid 运算符可以获取 type_info 类,从而进而获取到 class 的数值
- C++ 11 添加了限定作用域 enum
- 新的enum的作用域不在是全局的
- 不能隐式转换成其他类型
-
C++11 中声明成员指针最简单的方法是使用 auto 和 decltype 的
- 对象成员指针 和 对象成员函数指针:
- 首先的一个问题是,何必多此一举的首先将数据转换为指针,然后再访问
- 可以换一个名字访问
- 对于相同类型的成员函数指针,成员指针函数表是一个例子
- 生成可调用对象 : find_if(vec.begin(), vec.end()
- 使用 function 生成一个可调用对象
- 使用 mem_fn 可以解决 function 生成的时候必须显示的定义函数的参数类型
find_if(vec.begin(), vec.end(), mem_fn(string::empty)) - 还可以使用 bind 生成一个可调用的对象
find_if(vec.begin(), vec.end(), bind(string::empty, _1))
class Screen {
string contents = "A";
string contents2 = "B";
public:
static const string Screen::*getStringData() { return &Screen::contents; }
void get() { cout << "GET" << endl; }
};
int main(int argc, char *argv[]) {
const string Screen::*x = Screen::getStringData();
Screen s;
string a = s.*x;
cout << a << endl;
using GET = void (Screen::*)();
GET gg = &Screen::get;
(s.*gg)();
return 0;
}
using namespace std;
int main(int argc, char *argv[]) {
vector<string> str{"asdfaf", "", "asdf"};
// 不是 function<bool (const string *)> fp = &string::empty;
function<bool (const string &)> fp = &string::empty;
auto b = find_if(str.begin(), str.end(), fp);
b = find_if(str.begin(), str.end(), mem_fn(&string::empty));
b = find_if(str.begin(), str.end(), bind(&string::empty, std::placeholders::_1));
return 0;
}
WHEN COMMING BACK
- 内嵌类是很简答的,测试一下,main 函数中间可以访问一个 class 的内嵌类吗 ?
本站所有文章转发 CSDN 将按侵权追究法律责任,其它情况随意。