成员函数指针和幻像类

sla*_*ais 0 c++ member-function-pointers phantom-reference

我一直在讨论与前一个问题相关的成员函数指针.在下面的代码中,我调用类(B)上的方法来更改其中的变量(count),但我从不创建此类的实例.为什么这样做?

#include <iostream>
#include <string>
#include <map>

class A;
typedef int (A::*MEMFUNC)(int, int);

#define HANDLER(aclass, aproc) (MEMFUNC)(&aclass::aproc)

enum
{
    ADD=1,
    MUL,
    SUB,
    DIV
};

class B
{
    int count;
public:
    B() : count(0) {}
    ~B() {}
    int multiply(int x, int y) { count++; return x*y*count; }
    int divide(int x, int y) { count++; if (y!=0) return (x/y)*count; else return 0; }
};

class A
{
    std::map< int, MEMFUNC > funcs;
public:
    A() { AddLocals(); }
    ~A() {}
    int CallLocal(int nID, int x, int y)
    {
        MEMFUNC f = funcs[nID];
        if (f) return (this->*f)(x, y);
        else return 0;
    }
    void AddLocals()
    {
        Add(ADD, HANDLER(A, plus));
        Add(MUL, HANDLER(B, multiply));
        Add(SUB, HANDLER(A, subtract));
        Add(DIV, HANDLER(B, divide));
    }
    void Add(int nID, MEMFUNC f) { funcs[nID] = f; }
    int plus(int x, int y) { return x+y; }
    int subtract(int x, int y) { return x-y; }

};

int main()
{
    A aA;
    int a,b,c,d;

    a = aA.CallLocal(ADD,8,2);
    b = aA.CallLocal(MUL,8,2);
    c = aA.CallLocal(SUB,8,2);
    d = aA.CallLocal(DIV,8,2);

    std::cout << "a = " << a << "\n" 
              << "b = " << b << "\n" 
              << "c = " << c << "\n" 
              << "d = " << d << "\n";


    return 0;
}
Run Code Online (Sandbox Code Playgroud)

(对不起,我再次,但这个成员函数指针让我发痒)

Che*_*Alf 8

你在HANDLER宏def 中的演员告诉编译器"闭嘴!我知道我在做什么!".

所以编译器关闭了.

你仍然有未定义的行为,但UB的一个属性是,在某些情况下,它会做你天真期望的,或者你想要它做什么.

但是,如果这些代码崩溃,或导致崩溃或神秘不正确的结果显然完全不相关的代码,请不要感到惊讶.

或者,例如,导致鼻子恶魔飞出你的鼻子.

干杯和hth.