2012-05-17 4 views
2

많은 메뉴와 하위 메뉴로 C++에서 콘솔 응용 프로그램을 만들고 있습니다. 메뉴를 표시하는 방법은 do-while 루프를 사용하는 것입니다. 세 개의 매개 변수로 메뉴 루프를 표시하는 함수를 만들었습니다. 첫 번째는 메뉴에 몇 개의 옵션이 있는지에 관한 정수이고, 두 번째는 메뉴를 표시하는 함수이고 세 번째는 사용자가 입력 한 선택을 수행하는 다른 함수입니다. .C++ 오류 C2102 : '&'에 I 값이 필요합니다.

class Menu { 
public: 

void displayInitialMenu(){ 
     system("cls"); 
    string menu = "\n\t\tXXXXXXXXX"\ 
     "\n\n Please select from the following:"\ 
     "\n\n 1. XXXXXXX"\ 
     "\n\n 2. XXXXXXX"\ 
     "\n\n 3. Exit\n"; 
    cout << menu << endl; 
} 



static bool checkOption (int option, int lower, int upper){ 
if ((option < lower) || (option > upper)){ 
    return false; 
} else { 
    return true; 
} 
} 

static int readOption(int lower, int upper){ 

    int option = 0; 
    bool validMenuOption = false; 

    do{ 
     std::cin >> option; 
     validMenuOption = checkOption(option, lower, upper); 

     if (!validMenuOption){ 
      std::cout << "\nError: Input must be between " << lower; 
      std::cout << " and " << upper << "\n" << std::endl;  
     } 
    } while (!validMenuOption); 

    return option; 
} 
}; 

Menu menu; 

void menuLoop(int numberOfOptions, void (*displayMenu)(), void (*switchStatement)()){ 
int menuOption = numberOfOptions; 
do { 
    (*displayMenu)(); 
    menuOption = menu.readOption(1, numberOfOptions); 
    (*switchStatement)(); 
} while (menuOption != numberOfOptions); 
} 

static void performSelectionInitialMenu(int option){ 

switch (option){ 
case 1: 
    break; 

case 2: 
    break; 

case 3: 
    break; 

default: 
    break; 
} 
} 

int main() 
{ 
/* 
int menuOption = 3; 
do { 
    menu.displayInitialMenu(); 
    menuOption = menu.readOption(1, 3); 
    performSelectionInitialMenu(menuOption); 
} while (menuOption != 3); 
*/ 

menuLoop(3, &menu.displayInitialMenu(), &performSelectionInitialMenu(3)); 

return 0; 
} 

I 받고있어 오류가 입니다 : "오류 C2102은 '&는'L-값이 필요합니다." 프로그래밍에 익숙하지 않은데, 함수로 매개 변수를 전달하는 것은 이번이 처음입니다. 내가 주석 처리 한 코드를 제거하기 위해이 함수를 만들고 있습니다. 누구든지 내가 잘못하고 가능한 해결책을 지적 할 수 있습니다. 그렇지 않다면, 나는 나쁜 프로그래밍 실습이라고 알고있는 각 메뉴에 대해 중복 코드를 사용할 것입니다.

+1

** 최소 ** 코드를 게시하십시오. 온라인에서 질문하는 첫 번째 단계는 코드를 여전히 압축하여 문제를 해결하는 것입니다. 이것은 숙제의 일부이며, 우리의 과제를 훨씬 쉽게 만듭니다. –

+0

또한 오류 메시지를 게시 할 때 발생한 오류 번호를 포함하여 전체 오류 메시지를 게시하십시오. – irobot

답변

2

displayInitialMenuperformSelectionInitialMenu에 의해 반환 된 값의 주소를 가져 오려고하지만이 두 함수는 아무 것도 반환하지 않습니다 (void). 이 특정 문제를 해결하기 위해 두 호출 앞에 &을 제거하십시오.

+0

&를 제거했지만 이제는 새로운 오류가 발생합니다. C2664 : 'menuLoop': 매개 변수 2를 'void'에서 'void (_cdecl *) (void)'로 변환 할 수 없습니다. – Indy411

+0

아니요, 함수의 주소를 전달하기 위해 '&'가 필요합니다. 이 위치를 유지하면서 괄호를 제거하고 해당 기능 서명을 수정하십시오. – irobot

+0

고마워, 지금은 모두 작동 해. 도움 사람 들께 감사드립니다. – Indy411

2

일반적으로 당신은 단지 이런 식으로 부를 것이다 :

menuLoop(3, menu.displayInitialMenu, performSelectionInitialMenu); 

그냥, 매개 변수의 이름을 지정합니다.

그러나, performSelectionInitialMenu은 다음과 같습니다

void (*switchStatement)() 

가 호환되지 의미 :

static void performSelectionInitialMenu(int option) 

은 그래서 포인터의 서명과 일치하지 않습니다.

+0

그걸 보지 못했습니다. 잘 잡으세요! – irobot

+0

또한 Menu :: displayInitialMenu를 정적으로 만들어야합니다. – acraig5075

+0

감사합니다. 나는 그 오류가 발생했을 것입니다. – Indy411

0

우선, 함수 이름 뒤에 괄호를 붙이면 더 이상 함수 자체에 대해 말하는 것이 아닙니다. 즉 무료 함수 (클래스 멤버가 아닌 함수)의 경우 funcfunc의 주소를 참조하는 반면 func()은 해당 함수에서 반환되는 것이 무엇이든 참조합니다.

그래도 다른 문제가 있습니다. 비 정적 클래스 멤버 함수를 자유 함수로 전달하려고합니다. 비 정적 멤버 함수는 숨겨진 인수, 즉 호출 된 객체를 가지고 있기 때문에 이것은 C++에서 합법적이지 않습니다. 이론적으로 object.memberfunc은 호출 할 때 objectmemberfunc을 호출하는 대리자를 참조 할 수 있지만 C++에서는 그렇지 않습니다. C++에서 일반적으로 사용 되듯이 다양한 효과를 내기 위해 약 10 억 가지의 방법이 있습니다.

여러분 생각에 가장 쉬운 방법은 boost.bind입니다. 그래서, 당신이 뭘 하려는지 볼 것 같은 :

#include<boost/bind.hpp> 
using namespace boost; 

... 

template <class Functional> 
void menuLoop(int numberOfOptions, Funcional displayMenu, void (*switchStatement)()){ 

... 

menuLoop(3, bind(Menu::displayInitialMenu,menu), &performSelectionInitialMenu(3)); 

... 
0

menuLoop (3, & menu.displayInitialMenu(), & performSelectionInitialMenu (3));

달성하고자하는 것이 아닙니다. 첫째, 당신은 변수가 아닌 것들의 주소를 가져갈 수 없습니다.그래서, 당신은 다음을 수행해야합니다 :

  1. 는 "&"제거합니다.
  2. displayInitialMenu 및 performSelectionInitialMenu 다음에 "()"을 제거하십시오. 이러한 함수가 호출되고 현재의 경우 void 인 반환 값이 menuLoop에 전달된다는 의미이므로 performSelectionInitialMenu를 제거하십시오. 그래서, 당신은 달성하려는 것을 얻지 못할 것입니다.

당신은 같은 것을 할 필요가 :

menuLoop을 (3, menu.displayInitialMenu, performSelectionInitialMenu, 3); 추가 매개 변수로 3을 전달해야합니다.

또한 menuLoop의 서명을 적절하게 변경합니다.