C++:使用定位new分配函数指针

有时候在设计库的的时候,你可能需要根据上下文参数,决定某个对象是要完全动态创建,或者是分配在一个已知的地方。典型的如,对大于一定字节数的对象采用动态new,否则使用定位new表达式;而分配函数指针是少见的用法。

int foo(int x, int y)
{
    return x + y;
}

int main()
{
    // 声明函数指针类型
    using FunPtr = int(*)(int, int);

    // 平常的函数指针初始化方法
    FunPtr fptr1 = foo;
    fptr1(1, 2);

    // 注意类型void*
    void *fptr2 = nullptr;
    // 使用定位new初始化函数指针
    new (&fptr2)FunPtr(foo);
    ((FunPtr)fptr2)(1, 2);
}

如果没有理解上面的实现,我们用简单的int型解释。

int *p1 = nullptr;
new (&p1)int(8);    // p1指向内存地址编号为8的地方
int *p2 = (int*)8;  // 上面p1定位new相当于p2的做法

重点为是p1、p2指向的地址是8,而非指向的内容是8。当然,至于内存地址8处的内容是什么,我们不关心。如果还是觉得有点晦涩,我们还可以简单一点:让指针指向一个可以有效验证的地方。

// 让定位new指向一个可以有效验证的地方,即变量a的地址。
int a = 8;
int *p3 = &a;

int *p4 = nullptr;
*(&p4) = &a; // 等同于p3的初始化操作

int *p5 = nullptr;
new (&p5)int((int)&a); // 将a的地址解释为一个整数,
                       // 最终由p5将这个整数解释为一个地址,即a的地址。

打印一下

cout << "p1: " << p1 << "\n"
     << "p2: " << p2 << endl
     << "p3: " << p3 << "\n"
     << "p4: " << p4 << "\n"
     << "p5: " << p5 << endl;

下面是一组输出

p1: 00000008
p2: 00000008
p3: 00D2F76C
p4: 00D2F76C
p5: 00D2F76C

陕ICP备2025078817号-1 陕公网安备61011202001108号