欢迎光临
我们一直在努力

C++ Primer 第19章:特殊工具与技术

C++ Primer 第19章:特殊工具与技术


19.1 控制内存分配

19.1.1 重载 new 和 delete

// overload_new_delete.cpp — 重载new和delete
#include <iostream>
#include <cstdlib>
#include <cstring>
#include <stdexcept>

// ===== 全局 new/delete 重载 =====
// 通常不建议重载全局版本,会影响所有内存分配

// ===== 类级别的 new/delete 重载 =====
class MyClass
{
public:
   MyClass(int v = 0) : val_(v)
  {
       std::cout << "[构造] val=" << val_ << std::endl;
  }

   ~MyClass()
  {
       std::cout << "[析构] val=" << val_ << std::endl;
  }

   // 重载 operator new:分配内存
   static void* operator new(std::size_t size)
  {
       std::cout << "[new] 分配 " << size << " 字节" << std::endl;
       void* p = std::malloc(size);
       if (!p) throw std::bad_alloc();
       return p;
  }

   // 重载 operator delete:释放内存
   static void operator delete(void* p, std::size_t size) noexcept
  {
       std::cout << "[delete] 释放 " << size << " 字节" << std::endl;
       std::free(p);
  }

   // 重载数组版本
   static void* operator new[](std::size_t size)
  {
       std::cout << "[new[]] 分配 " << size << " 字节" << std::endl;
       void* p = std::malloc(size);
       if (!p) throw std::bad_alloc();
       return p;
  }

   static void operator delete[](void* p, std::size_t size) noexcept
  {
       std::cout << "[delete[]] 释放 " << size << " 字节" << std::endl;
       std::free(p);
  }

   int val() const { return val_; }

private:
   int val_;
};

int main()
{
   using namespace std;

   cout << "===== 单个对象 =====" << endl;
   MyClass* p = new MyClass(42);   // 调用 operator new,然后构造函数
   cout << "val = " << p->val() << endl;
   delete p;   // 调用析构函数,然后 operator delete

   cout << "\\n===== 对象数组 =====" << endl;
   MyClass* arr = new MyClass[3];   // 调用 operator new[]
   delete[] arr;                    // 调用 operator delete[]

   return 0;
}


19.1.2 定位 new(placement new)

// placement_new.cpp — 定位new
#include <iostream>
#include <new>
#include <string>

class Widget
{
public:
   Widget(const std::string& name) : name_(name)
  {
       std::cout << "[构造] " << name_ << std::endl;
  }
   ~Widget()
  {
       std::cout << "[析构] " << name_ << std::endl;
  }
   void show() const { std::cout << "Widget: " << name_ << std::endl; }

private:
   std::string name_;
};

int main()
{
   using namespace std;

   // ===== 定位new:在指定内存上构造对象 =====
   // 语法:new (地址) 类型(参数)

   // 在栈上分配内存
   alignas(Widget) char buffer[sizeof(Widget)];

   // 在 buffer 上构造 Widget(不分配内存)
   Widget* p = new (buffer) Widget("栈上的Widget");
   p->show();

   // 必须手动调用析构函数!(不能用 delete)
   p->~Widget();

   // ===== 在堆上预分配内存,然后构造 =====
   void* raw = ::operator new(sizeof(Widget));   // 只分配内存
   Widget* p2 = new (raw) Widget("堆上的Widget");
   p2->show();
   p2->~Widget();                // 手动析构
  ::operator delete(raw);       // 手动释放内存

   // ===== 对象池示例 =====
   cout << "\\n===== 对象池 =====" << endl;
   const int POOL_SIZE = 3;
   alignas(Widget) char pool[sizeof(Widget) * POOL_SIZE];

   // 在池中构造多个对象
   Widget* widgets[POOL_SIZE];
   for (int i = 0; i < POOL_SIZE; i++)
  {
       widgets[i] = new (pool + i * sizeof(Widget))
                    Widget("池对象" + to_string(i));
  }

   for (int i = 0; i < POOL_SIZE; i++)
       widgets[i]->show();

   // 手动析构(逆序)
   for (int i = POOL_SIZE – 1; i >= 0; i–)
       widgets[i]->~Widget();

   return 0;
}


19.2 运行时类型识别(RTTI)

19.2.1 dynamic_cast

// dynamic_cast_demo.cpp — dynamic_cast详解
#include <iostream>
#include <memory>
#include <string>

class Shape
{
public:
   virtual double area() const = 0;
   virtual std::string name() const = 0;
   virtual ~Shape() {}
};

class Circle : public Shape
{
public:
   Circle(double r) : radius_(r) {}
   double area() const override { return 3.14159 * radius_ * radius_; }
   std::string name() const override { return "Circle"; }
   double radius() const { return radius_; }

private:
   double radius_;
};

class Rectangle : public Shape
{
public:
   Rectangle(double w, double h) : w_(w), h_(h) {}
   double area() const override { return w_ * h_; }
   std::string name() const override { return "Rectangle"; }
   double width()  const { return w_; }
   double height() const { return h_; }

private:
   double w_, h_;
};

int main()
{
   using namespace std;

   Shape* shapes[] = {
       new Circle(5.0),
       new Rectangle(4.0, 6.0),
       new Circle(3.0)
  };

   cout << "===== dynamic_cast 指针版本 =====" << endl;
   for (auto s : shapes)
  {
       cout << s->name() << " 面积=" << s->area() << endl;

       // 向下转型:成功返回有效指针,失败返回 nullptr
       if (Circle* c = dynamic_cast<Circle*>(s))
      {
           cout << " 半径=" << c->radius() << endl;
      }
       else if (Rectangle* r = dynamic_cast<Rectangle*>(s))
      {
           cout << " 宽=" << r->width() << " 高=" << r->height() << endl;
      }
  }

   cout << "\\n===== dynamic_cast 引用版本 =====" << endl;
   // 引用版本:失败时抛出 std::bad_cast
   try
  {
       Shape& s = *shapes[0];   // Circle
       Circle& c = dynamic_cast<Circle&>(s);   // 成功
       cout << "Circle半径:" << c.radius() << endl;

       Shape& s2 = *shapes[1];   // Rectangle
       Circle& c2 = dynamic_cast<Circle&>(s2);   // 失败!抛出 bad_cast
  }
   catch (const bad_cast& e)
  {
       cout << "bad_cast:" << e.what() << endl;
  }

   for (auto s : shapes) delete s;
   return 0;
}


19.2.2 typeid 运算符

// typeid_demo.cpp — typeid运算符
#include <iostream>
#include <typeinfo>
#include <string>

class Base
{
public:
   virtual ~Base() {}
   virtual std::string type() const { return "Base"; }
};

class Derived : public Base
{
public:
   std::string type() const override { return "Derived"; }
};

int main()
{
   using namespace std;

   // ===== typeid 基本用法 =====
   int    i = 42;
   double d = 3.14;
   string s = "Hello";

   // typeid 返回 type_info 对象的引用
   cout << "int:   " << typeid(i).name() << endl;
   cout << "double: " << typeid(d).name() << endl;
   cout << "string: " << typeid(s).name() << endl;

   // ===== typeid 与多态 =====
   cout << "\\n===== 多态类型 =====" << endl;
   Base b;
   Derived d2;
   Base* p1 = &b;
   Base* p2 = &d2;

   // 对指针使用 typeid:返回指针类型(不是所指对象的类型)
   cout << "typeid(p1): " << typeid(p1).name() << endl;   // Base*

   // 对解引用指针使用 typeid:返回实际对象类型(动态类型)
   cout << "typeid(*p1): " << typeid(*p1).name() << endl;  // Base
   cout << "typeid(*p2): " << typeid(*p2).name() << endl;  // Derived

   // ===== 类型比较 =====
   cout << "\\n===== 类型比较 =====" << endl;
   cout << boolalpha;
   cout << "p1指向Base:" << (typeid(*p1) == typeid(Base)) << endl;
   cout << "p2指向Derived:" << (typeid(*p2) == typeid(Derived)) << endl;
   cout << "p1和p2类型相同:" << (typeid(*p1) == typeid(*p2)) << endl;

   // ===== 实际应用:类型安全的操作 =====
   cout << "\\n===== 类型安全操作 =====" << endl;
   Base* shapes[] = {new Base(), new Derived(), new Base()};

   for (auto s : shapes)
  {
       if (typeid(*s) == typeid(Derived))
           cout << "这是Derived对象" << endl;
       else
           cout << "这是Base对象" << endl;
       delete s;
  }

   return 0;
}


19.3 枚举类型

// enum_types.cpp — 枚举类型
#include <iostream>
#include <string>

// ===== 传统枚举(不限定作用域)=====
enum Color { RED, GREEN, BLUE };   // RED=0, GREEN=1, BLUE=2
enum Status { ACTIVE, INACTIVE };

// ⚠️ 传统枚举的问题:
// 1. 枚举值泄漏到外层作用域
// 2. 不同枚举类型可以比较(隐式转换为int)
// 3. 不能指定底层类型(默认int)

// ===== 限定作用域的枚举(C++11)=====
enum class Direction { NORTH, SOUTH, EAST, WEST };
enum class Permission : uint8_t   // 指定底层类型
{
   NONE    = 0,
   READ    = 1,
   WRITE   = 2,
   EXECUTE = 4,
   ALL     = READ | WRITE | EXECUTE
};

// ===== 枚举的前置声明(C++11)=====
enum class Season : int;   // 前置声明
void printSeason(Season s);

enum class Season : int { SPRING, SUMMER, AUTUMN, WINTER };

void printSeason(Season s)
{
   switch (s)
  {
       case Season::SPRING: std::cout << "春天" << std::endl; break;
       case Season::SUMMER: std::cout << "夏天" << std::endl; break;
       case Season::AUTUMN: std::cout << "秋天" << std::endl; break;
       case Season::WINTER: std::cout << "冬天" << std::endl; break;
  }
}

int main()
{
   using namespace std;

   // 传统枚举
   Color c = RED;
   int n = c;   // ✅ 隐式转换为int
   // Color c2 = 0;   // ❌ 不能从int转换

   // 不同枚举类型可以比较(危险!)
   // if (RED == ACTIVE) {}   // 编译通过,但语义错误

   // 限定作用域枚举
   Direction d = Direction::NORTH;
   // int m = d;   // ❌ 不能隐式转换
   int m = static_cast<int>(d);   // ✅ 必须显式转换

   // 不同枚举类型不能比较
   // if (Direction::NORTH == Season::SPRING) {}   // ❌ 编译错误

   // 权限枚举
   Permission perm = Permission::READ;
   cout << "READ = " << static_cast<int>(perm) << endl;

   // 使用位运算(需要显式转换)
   auto combined = static_cast<Permission>(
       static_cast<uint8_t>(Permission::READ) |
       static_cast<uint8_t>(Permission::WRITE));
   cout << "READ|WRITE = " << static_cast<int>(combined) << endl;

   // 季节枚举
   printSeason(Season::AUTUMN);

   // 枚举的大小
   cout << "\\n枚举大小:" << endl;
   cout << "Color: " << sizeof(Color) << " 字节" << endl;
   cout << "Permission: " << sizeof(Permission) << " 字节" << endl;

   return 0;
}


19.4 类成员指针

// member_pointer.cpp — 类成员指针
#include <iostream>
#include <string>
#include <vector>
#include <algorithm>
#include <functional>

class Screen
{
public:
   using Action = Screen& (Screen::*)();   // 成员函数指针类型别名

   Screen(int h, int w, char c)
      : height_(h), width_(w), contents_(h * w, c), cursor_(0) {}

   // 成员函数
   Screen& home() { cursor_ = 0; return *this; }
   Screen& end()   { cursor_ = contents_.size() – 1; return *this; }
   Screen& forward()
  {
       if (cursor_ < contents_.size() – 1) ++cursor_;
       return *this;
  }
   Screen& back()
  {
       if (cursor_ > 0) –cursor_;
       return *this;
  }

   char get() const { return contents_[cursor_]; }
   int  pos() const { return cursor_; }

   // 数据成员
   int         height_, width_;
   std::string contents_;
   int         cursor_;
};

int main()
{
   using namespace std;

   Screen s(3, 5, 'X');

   // ===== 数据成员指针 =====
   // 声明:类型 类名::*指针名
   int Screen::*pHeight = &Screen::height_;
   int Screen::*pWidth  = &Screen::width_;

   // 通过对象使用成员指针
   cout << "height = " << s.*pHeight << endl;   // 3
   cout << "width = " << s.*pWidth  << endl;   // 5

   // 通过指针使用成员指针
   Screen* ps = &s;
   cout << "height = " << ps->*pHeight << endl;

   // ===== 成员函数指针 =====
   // 声明:返回类型 (类名::*指针名)(参数类型)
   Screen& (Screen::*pForward)() = &Screen::forward;
   Screen& (Screen::*pBack)()    = &Screen::back;

   // 通过对象调用
  (s.*pForward)();
   cout << "前进后位置:" << s.pos() << endl;

  (s.*pBack)();
   cout << "后退后位置:" << s.pos() << endl;

   // 通过指针调用
  (ps->*pForward)();
   cout << "通过指针前进:" << s.pos() << endl;

   // ===== 成员函数指针数组 =====
   Screen::Action actions[] = {
       &Screen::home,
       &Screen::forward,
       &Screen::end,
       &Screen::back
  };

   // 执行所有动作
   for (auto action : actions)
      (s.*action)();

   // ===== 使用 std::mem_fn 和 std::bind =====
   cout << "\\n===== mem_fn 和 bind =====" << endl;

   // mem_fn:将成员函数包装为可调用对象
   auto getPos = mem_fn(&Screen::pos);
   cout << "pos = " << getPos(s) << endl;

   // bind:绑定成员函数
   auto forward = bind(&Screen::forward, &s);
   forward();
   cout << "bind forward后:" << s.pos() << endl;

   return 0;
}


19.5 嵌套类

// nested_class.cpp — 嵌套类
#include <iostream>
#include <string>
#include <memory>

// 嵌套类:定义在另一个类内部的类
class TextQuery
{
public:
   // 嵌套类:QueryResult
   class QueryResult
  {
       friend class TextQuery;

   public:
       QueryResult(const std::string& word, int count)
          : word_(word), count_(count) {}

       void print() const
      {
           std::cout << "\\"" << word_ << "\\" 出现 "
                     << count_ << " 次" << std::endl;
      }

       int count() const { return count_; }

   private:
       std::string word_;
       int         count_;
  };

   // TextQuery 的成员
   void addWord(const std::string& word)
  {
       wordCount_[word]++;
  }

   QueryResult query(const std::string& word) const
  {
       auto it = wordCount_.find(word);
       int count = (it != wordCount_.end()) ? it->second : 0;
       return QueryResult(word, count);
  }

private:
   std::map<std::string, int> wordCount_;
};

// 在类外定义嵌套类的成员
// TextQuery::QueryResult::QueryResult(…) { … }

int main()
{
   using namespace std;

   TextQuery tq;
   string text = "the quick brown fox jumps over the lazy dog the";

   // 分词并统计
   istringstream iss(text);
   string word;
   while (iss >> word)
       tq.addWord(word);

   // 查询
   auto result1 = tq.query("the");
   auto result2 = tq.query("fox");
   auto result3 = tq.query("cat");

   result1.print();   // "the" 出现 3 次
   result2.print();   // "fox" 出现 1 次
   result3.print();   // "cat" 出现 0 次

   return 0;
}


19.6 union:一种节省空间的类

// union_demo.cpp — union
#include <iostream>
#include <string>
#include <new>

// ===== 基本 union =====
union Data
{
   int    ival;
   double dval;
   char   cval;
};   // 大小等于最大成员的大小

// ===== 匿名 union =====
struct Token
{
   enum class TokenKind { INT, DOUBLE, STRING };
   TokenKind kind;

   union   // 匿名union:成员直接在外层作用域可见
  {
       int    ival;
       double dval;
       // std::string sval;   // ⚠️ 含有构造函数的类型需要特殊处理
  };
};

// ===== 含有类类型成员的 union =====
class MyUnion
{
public:
   enum class Type { INT, STRING, NONE };

   MyUnion() : type_(Type::NONE) {}

   MyUnion(int v) : type_(Type::INT)
  {
       new (&ival_) int(v);   // 定位new
  }

   MyUnion(const std::string& s) : type_(Type::STRING)
  {
       new (&sval_) std::string(s);   // 定位new
  }

   MyUnion(const MyUnion& other) : type_(other.type_)
  {
       switch (type_)
      {
           case Type::INT:    new (&ival_) int(other.ival_); break;
           case Type::STRING: new (&sval_) std::string(other.sval_); break;
           default: break;
      }
  }

   ~MyUnion()
  {
       if (type_ == Type::STRING)
           sval_.~basic_string<char>();   // 手动析构
  }

   void show() const
  {
       switch (type_)
      {
           case Type::INT:    std::cout << "int: " << ival_ << std::endl; break;
           case Type::STRING: std::cout << "string: " << sval_ << std::endl; break;
           default: std::cout << "none" << std::endl;
      }
  }

private:
   Type type_;
   union
  {
       int         ival_;
       std::string sval_;
  };
};

int main()
{
   using namespace std;

   // 基本 union
   Data d;
   d.ival = 42;
   cout << "ival = " << d.ival << endl;

   d.dval = 3.14;   // 覆盖了 ival
   cout << "dval = " << d.dval << endl;
   // d.ival 现在是未定义的

   cout << "union大小:" << sizeof(Data) << " 字节" << endl;

   // 含类类型的 union
   MyUnion u1(42);
   MyUnion u2(string("Hello"));
   MyUnion u3;

   u1.show();
   u2.show();
   u3.show();

   return 0;
}


19.7 局部类

// local_class.cpp — 局部类
#include <iostream>
#include <string>
#include <functional>

// 局部类:定义在函数内部的类
std::function<int(int)> makeAdder(int n)
{
// 局部类
class Adder
{
public:
Adder(int n) : n_(n) {}
int operator()(int x) const { return x + n_; }

private:
int n_;
// ⚠️ 局部类的限制:
// 1. 不能定义静态数据成员
// 2. 不能访问外层函数的局部变量(除非是静态的)
// 3. 可以访问外层函数的类型名、静态变量、枚举值
};

return Adder(n);
}

// 局部类在模板中的应用
template <typename T>
std::function<bool(T)> makeGreaterThan(T threshold)
{
class Comparator
{
public:
Comparator(T t) : threshold_(t) {}
bool operator()(T val) const { return val > threshold_; }

private:
T threshold_;
};

return Comparator(threshold);
}

int main()
{
using namespace std;

auto add5 = makeAdder(5);
auto add10 = makeAdder(10);

cout << "add5(3) = " << add5(3) << endl; // 8
cout << "add10(3) = " << add10(3) << endl; // 13

auto gt5 = makeGreaterThan(5);
auto gt10 = makeGreaterThan(10.0);

cout << boolalpha;
cout << "7 > 5: " << gt5(7) << endl; // true
cout << "3 > 5: " << gt5(3) << endl; // false
cout << "15.0 > 10.0: " << gt10(15.0) << endl; // true

return 0;
}


19.8 固有的不可移植的特性

19.8.1 位域

// bit_fields.cpp — 位域
#include <iostream>

// 位域:允许将多个标志位打包到一个整数中
struct NetworkPacket
{
unsigned int version : 4; // 4位:版本号(0-15)
unsigned int type : 4; // 4位:类型(0-15)
unsigned int flags : 8; // 8位:标志位
unsigned int length : 16; // 16位:长度(0-65535)
// 总共 32 位 = 4 字节
};

struct Permissions
{
unsigned int read : 1; // 1位
unsigned int write : 1; // 1位
unsigned int execute : 1; // 1位
unsigned int : 5; // 5位填充(未命名)
};

int main()
{
using namespace std;

NetworkPacket pkt;
pkt.version = 4;
pkt.type = 2;
pkt.flags = 0b00000001;
pkt.length = 1024;

cout << "版本:" << pkt.version << endl;
cout << "类型:" << pkt.type << endl;
cout << "标志:" << pkt.flags << endl;
cout << "长度:" << pkt.length << endl;
cout << "结构体大小:" << sizeof(NetworkPacket) << " 字节" << endl;

Permissions perm = {1, 1, 0};
cout << "\\n读权限:" << perm.read << endl;
cout << "写权限:" << perm.write << endl;
cout << "执行权限:" << perm.execute << endl;

return 0;
}


19.8.2 volatile 限定符

// volatile_demo.cpp — volatile
#include <iostream>

// volatile:告诉编译器不要优化该变量
// 每次访问都从内存读取,不使用缓存

// 常见用途:
// 1. 硬件寄存器
// 2. 多线程共享变量(但不能替代互斥锁)
// 3. 信号处理程序中的变量

volatile int hardwareReg = 0; // 模拟硬件寄存器

// volatile 与 const 组合
volatile const int readOnlyReg = 0xFF; // 只读硬件寄存器

void readHardware()
{
// 每次都从内存读取,不会被优化为只读一次
for (int i = 0; i < 3; i++)
std::cout << "寄存器值:" << hardwareReg << std::endl;
}

// volatile 成员函数
class HardwareDevice
{
public:
void read() volatile
{
// 可以被 volatile 对象调用
std::cout << "读取设备" << std::endl;
}

void write() volatile
{
std::cout << "写入设备" << std::endl;
}
};

int main()
{
readHardware();

volatile HardwareDevice dev;
dev.read();
dev.write();

return 0;
}


19.8.3 链接指示(extern "C")

// extern_c.cpp — 链接指示
#include <iostream>

// extern "C":告诉编译器使用C语言的链接规则
// 主要用于与C代码互操作

// 单个函数
extern "C" void c_function(int x)
{
// 使用C链接,函数名不会被C++名字修饰
std::cout << "C函数:" << x << std::endl;
}

// 多个函数
extern "C"
{
void c_func1() { std::cout << "c_func1" << std::endl; }
void c_func2() { std::cout << "c_func2" << std::endl; }
int c_add(int a, int b) { return a + b; }
}

// 包含C头文件
// extern "C"
// {
// #include <stdio.h>
// #include <string.h>
// }

// 在头文件中同时支持C和C++
#ifdef __cplusplus
extern "C" {
#endif

void shared_function(int x)
{
std::cout << "共享函数:" << x << std::endl;
}

#ifdef __cplusplus
}
#endif

int main()
{
c_function(42);
c_func1();
c_func2();
std::cout << "c_add(3,4) = " << c_add(3, 4) << std::endl;
shared_function(100);

return 0;
}


19.9 综合示例:内存池

// memory_pool.cpp — 综合示例:内存池
#include <iostream>
#include <vector>
#include <string>
#include <stdexcept>
#include <new>
#include <cstring>

// 固定大小的内存池
template <typename T, size_t BlockSize = 64>
class MemoryPool
{
private:
// 内存块
struct Block
{
alignas(T) char data[sizeof(T)];
bool inUse = false;
};

std::vector<Block> pool_;
size_t allocated_ = 0;

public:
MemoryPool() : pool_(BlockSize) {}

// 分配内存
T* allocate()
{
for (auto& block : pool_)
{
if (!block.inUse)
{
block.inUse = true;
++allocated_;
return reinterpret_cast<T*>(block.data);
}
}
throw std::bad_alloc();
}

// 释放内存
void deallocate(T* p) noexcept
{
for (auto& block : pool_)
{
if (reinterpret_cast<T*>(block.data) == p)
{
block.inUse = false;
–allocated_;
return;
}
}
}

// 构造对象
template <typename… Args>
T* construct(Args&&… args)
{
T* p = allocate();
try
{
new (p) T(std::forward<Args>(args)…); // 定位new
}
catch (…)
{
deallocate(p);
throw;
}
return p;
}

// 析构并释放
void destroy(T* p) noexcept
{
p->~T();
deallocate(p);
}

size_t allocated() const { return allocated_; }
size_t capacity() const { return pool_.size(); }
size_t available() const { return capacity() – allocated(); }
};

// 使用内存池的类
class Widget
{
public:
Widget(const std::string& name, int val)
: name_(name), val_(val)
{
std::cout << "[构造] " << name_ << "(" << val_ << ")" << std::endl;
}

~Widget()
{
std::cout << "[析构] " << name_ << std::endl;
}

void show() const
{
std::cout << "Widget: " << name_ << " = " << val_ << std::endl;
}

private:
std::string name_;
int val_;
};

int main()
{
using namespace std;

MemoryPool<Widget, 5> pool;

cout << "===== 内存池状态 =====" << endl;
cout << "容量:" << pool.capacity() << endl;
cout << "可用:" << pool.available() << endl;

cout << "\\n===== 分配对象 =====" << endl;
Widget* w1 = pool.construct("Widget1", 100);
Widget* w2 = pool.construct("Widget2", 200);
Widget* w3 = pool.construct("Widget3", 300);

cout << "已分配:" << pool.allocated() << endl;

w1->show();
w2->show();
w3->show();

cout << "\\n===== 释放对象 =====" << endl;
pool.destroy(w2);
cout << "释放w2后,已分配:" << pool.allocated() << endl;

cout << "\\n===== 复用内存 =====" << endl;
Widget* w4 = pool.construct("Widget4", 400); // 复用w2的内存
w4->show();

cout << "\\n===== 清理 =====" << endl;
pool.destroy(w1);
pool.destroy(w3);
pool.destroy(w4);
cout << "最终已分配:" << pool.allocated() << endl;

return 0;
}


📝 第19章知识点总结

知识点核心要点
重载 new/delete 类级别重载,operator new 分配内存,operator delete 释放
定位 new new (地址) 类型(参数),在指定内存构造,必须手动调用析构函数
dynamic_cast 安全向下转型,指针版本失败返回nullptr,引用版本失败抛bad_cast
typeid 返回 type_info,对多态类型返回动态类型,对指针返回静态类型
enum class 限定作用域,不隐式转换为int,可指定底层类型,推荐使用
数据成员指针 类型 类名::*ptr = &类名::成员,通过 .* 或 ->* 使用
成员函数指针 返回类型 (类名::*ptr)(参数),通过 .* 或 ->* 调用
mem_fn 将成员函数包装为可调用对象
嵌套类 定义在类内部,有自己的作用域,外层类不能直接访问嵌套类的私有成员
union 所有成员共享内存,大小等于最大成员,含类类型成员需手动管理
局部类 定义在函数内部,不能有静态数据成员,不能访问外层局部变量
位域 指定成员占用的位数,节省内存,常用于硬件协议
volatile 防止编译器优化,每次从内存读取,用于硬件寄存器和信号处理
extern "C" 使用C链接规则,用于C/C++互操作,防止名字修饰
赞(0)
未经允许不得转载:171主机测评 » C++ Primer 第19章:特殊工具与技术
分享到: 更多 (0)

评论 抢沙发

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址