Skip to the content.

19

  1. 当我们想要自定义 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; }
  1. 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,也就是资源分配的行为
  2. 不能定义 void operator new(size_t, void *) 的 overload 函数,因为这是给标准库使用的

  3. 当 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;
}
  1. 使用 RTTI 在实现 equal 函数非常方便
    • 首先比较 RTTI 保证 lhs 和 rhs 类型
    • 定义 virtual equal(const Base & b), 在 base 中间,这个函数的权限是 protected
    • 最后定义 operator ==
  2. 通过 typeid 运算符可以获取 type_info 类,从而进而获取到 class 的数值

  3. C++ 11 添加了限定作用域 enum
    • 新的enum的作用域不在是全局的
    • 不能隐式转换成其他类型
  4. C++11 中声明成员指针最简单的方法是使用 auto 和 decltype 的

  5. 对象成员指针 和 对象成员函数指针:
    • 首先的一个问题是,何必多此一举的首先将数据转换为指针,然后再访问
    • 可以换一个名字访问
    • 对于相同类型的成员函数指针,成员指针函数表是一个例子
    • 生成可调用对象 : 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

本站所有文章转发 CSDN 将按侵权追究法律责任,其它情况随意。