【问题标题】:C++ Pointer to function as argument. Data types incompatibilityC++ 指向函数作为参数的指针。数据类型不兼容
【发布时间】:2013-12-01 11:50:27
【问题描述】:

我在查找代码中的错误原因时遇到了一些麻烦,我想向您寻求帮助。我昨天已经问过类似的问题,但后来我想我找到了原因。今天早上编译器再次证明我错了......

错误说:

IntelliSense: argument of type "void (Transaction::*)()" is incompatible with parameter of type "eventPointer"

error C2664: 'Calendar::calendarPush' : cannot convert parameter 3 from 'void (__thiscall Transaction::* )(void)' to 'eventPointer'

导致错误的代码可以在 eb 中找到

Main.cpp, line (calling of the method)
Calendar::calendarPush(1, 1, &Transaction::event1);

Calendar.cpp line (definition of the method)
void Calendar::calendarPush(double Time, int Priority, eventPointer event)

eventPointer的定义见

Calendar.h, line
typedef void (Calendar::*eventPointer) ();

我看不出这两者是如何不相容的。怎么了? :/

代码如下:

----------MAIN.CPP----------

#include <iostream>

#include "Calendar.cpp"
#include "Transaction.cpp"

using namespace std;

int main() {

    cout << "Initializing" << endl;

    double Time = 0.0;
    int Priority = 0;

    cout << "Pushing initial event" << endl;

    Calendar::calendarPush(1, 1, &Transaction::event1);

}

----------CALENDAR.H----------

#include <iostream>
#include <queue>

using namespace std;

class Calendar;

typedef void (Calendar::*eventPointer) ();

struct activationRecord {
    double Time;
    int Priority;
    eventPointer activationEvent;
};


bool operator < (const activationRecord & a, const activationRecord & b);

class Calendar {

private:
    static std::priority_queue<activationRecord> activationCalendar;

public:
    bool calendarEmpty();

    static void calendarPush(double, int, eventPointer);

    activationRecord calendarTop();
    void calendarPop();

    void calendarRun();
};


----------CALENDAR.CPP-----------

#include "Calendar.h"

bool Calendar::calendarEmpty() {

    return activationCalendar.empty();
}

void Calendar::calendarPush(double Time, int Priority, eventPointer event) {

    activationRecord record;

    record.Time = Time;
    record.Priority = Priority;
    record.activationEvent = event;

    activationCalendar.push(record);
}

activationRecord Calendar::calendarTop() {

    return activationCalendar.top();
}

void Calendar::calendarPop() {

    activationCalendar.pop();
}

void Calendar::calendarRun() {

    activationRecord record;

    while(!calendarEmpty()) {
        record = calendarTop();
        calendarPop();

        cout << record.Time << endl;
        cout << record.Priority << endl;
        cout << record.activationEvent << endl << endl; 

    }
}

bool operator < (const activationRecord & a, const activationRecord & b) {
    return a.Time > b.Time;
}

----------TRANSACTION.H----------

#include <iostream>

using namespace std;


class Transaction {

public:
    void event1();
    void event2();
    void event3();
    void event4();
    void event5();

};

----------TRANSACTION.CPP-----------

#include <iostream>

#include "Transaction.h"

using namespace std;

void event1() {

    cout << "event1" << endl;


}

void event2() {

    cout << "event2" << endl;


}

void event3() {

    cout << "event3" << endl;


}

void event4() {

    cout << "event4" << endl;


}

void event5() {

    cout << "event5" << endl;
}

现在突然间我遇到了更多的错误,这对我来说更没有意义。

error C2027: use of undefined type 'Transaction'

error C2065: 'event1' : undeclared identifier

error C2011: 'Transaction' : 'class' type redefinition

我只是不明白怎么会发生这样的事情,这似乎与我的代码包含的内容直接不一致。

我宁愿再次粘贴整个代码,以防我搞砸了我看不到的东西:

----------MAIN.CPP----------

#include <iostream>

#include "Calendar.h"
#include "Transaction.h"

using namespace std;

int main() {

    cout << "Inicializuji" << endl;

    double Time = 0.0;
    int Priority = 0;

    cout << "Vlkadam uvodni udalost" << endl;

    Calendar::calendarPush(1, 1, &Transaction::event1);

}

----------CALENDAR.H----------

#include <iostream>
#include <queue>

#include "Transaction.h"

using namespace std;

typedef void (Transaction::*eventPointer) ();

struct activationRecord {
    double Time;
    int Priority;
    eventPointer activationEvent;
};


bool operator < (const activationRecord & a, const activationRecord & b);

class Calendar {

private:
    static std::priority_queue<activationRecord> activationCalendar;

public:
    bool calendarEmpty();

    static void calendarPush(double, int, eventPointer);

    activationRecord calendarTop();
    void calendarPop();

    void calendarRun();
};


----------CALENDAR.CPP-----------

#include "Calendar.h"

bool Calendar::calendarEmpty() {

    return activationCalendar.empty();
}

void Calendar::calendarPush(double Time, int Priority, eventPointer event) {

    activationRecord record;

    record.Time = Time;
    record.Priority = Priority;
    record.activationEvent = event;

    activationCalendar.push(record);
}

activationRecord Calendar::calendarTop() {

    return activationCalendar.top();
}

void Calendar::calendarPop() {

    activationCalendar.pop();
}

void Calendar::calendarRun() {

    activationRecord record;

    while(!calendarEmpty()) {
        record = calendarTop();
        calendarPop();

        cout << record.Time << endl;
        cout << record.Priority << endl;
        cout << record.activationEvent << endl << endl; 

    }
}

bool operator < (const activationRecord & a, const activationRecord & b) {
    return a.Time > b.Time;
}   

----------TRANSACTION.H----------

#include <iostream>

using namespace std;

class Transaction {

public:
    void event1();
};


----------TRANSACTION.CPP-----------

#include "Transaction.h"

using namespace std;

void Transaction::event1() {

}   

请帮忙。

【问题讨论】:

  • “我看不出这两个怎么不兼容。”他们是。 Pointer-to-member-function-of-class-A 与 Pointer-to-member-function-of-class-B 不兼容(除非 A 和 B 之间存在关系)。
  • 问题是,当我将 Calendar.h 中 eventPointer 的声明更改为 typedef void (Transaction::*eventPointer) ();。问题仍然存在。因为我必须在 Calendar.h 中包含 Transaction.h,所以我遇到了更多错误,例如错误 C2027:使用未定义类型“事务”,错误 C2011:“事务”:“类”类型重新定义,然后是旧的“void (Transaction::*)()”类型的参数与“eventPointer”类型的参数不兼容,错误 C2664:“Calendar::calendarPush”:无法将参数 3 从“void (__cdecl *)(void)”转换为'eventPointer'. 所以很困惑。

标签: c++ function pointers arguments


【解决方案1】:

问题是因为它们是指向成员函数的指针。尽管它们具有相同的返回类型和参数类型,但它们被认为是不同的类型,因为它们是不相关类的成员。

当您指定您的参数为void (Calendar::*)() 类型时,只有Calendar 的成员函数可以转换为它。

解决问题的一种方法是让Calendar 使用void (*)() 而不是void (Calendar::*)()。然后将Transactionevent成员函数改为static函数。然后event 函数的类型将是void (*)() 而不是void (Transaction::*)()

另一种方法是将eventPointer 更改为void (Transaction::*)() 类型,以便转换工作。此外,您的Transaction.cpp 目前似乎定义了void event1(); 而不是void Transaction::event1();,这将导致一些未定义的函数相关错误。

【讨论】:

  • mpark 你能给出一个代码示例来说明“void (*)()”是什么意思
  • @Jammi: 如果我们有一个函数:void f() {}f 的类型是void ()&amp;ff 的地址)的类型是void (*)()
猜你喜欢
  • 2021-02-26
  • 2015-03-02
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-10-11
  • 2016-10-10
  • 2013-11-06
  • 2011-05-11
相关资源
最近更新 更多