• 카테고리

    질문 & 답변
  • 세부 분야

    프로그래밍 언어

  • 해결 여부

    미해결

상속-base class undefined

23.12.07 03:27 작성 23.12.07 03:46 수정 조회수 169

1

안녕하세요, 제가 며칠 잠을 못자서 그런지 계속 상속에서 에러가 나네요..

개념도 다시 한번 정비하려고 강의도 정주행 중인데, 며칠 째 못풀어서 답답해서 일단 질문드립니다.ㅠ

조금 긴 코드이지만 염치 불구하고 혹시 도와주신다면 정말로 감사할 것 같습니다.

  • 우선, menu를 userMenu에서 상속받고 몇가지 변수들도 추가하고자 하여, virtual function-override를 사용해보았습니다.

  • 그런데 계속해서

  • Severity Code Description Project File Line Suppression State

    Error C3668 'UserMenu::handleEvents': method with override specifier 'override' did not override any base class methods

  • Severity Code Description Project File Line Suppression State

    Error C2504 'Menu': base class undefined

  • 이와 같은 오류가 납니다.

  • virtual function 선언 때 0을 부여해도 마찬가지입니다.

 

// 우선 userMenu.h 와 .cpp 입니다.
#pragma once
#ifndef USER_MENU_H
#define USER_MENU_H
#include "menu.h"
#include "gameDisplay.h"

class UserMenu : public Menu {
public:
    UserMenu();
    void u_run();  
    void handleEvents() override;
protected:
    sf::Text subText;
    sf::Text buttonSecond;
    sf::RectangleShape borderSecond;
    sf::Text buttonThird;
    sf::RectangleShape borderThird;
};
#endif 

// .cpp
#include "userMenu.h"

UserMenu::UserMenu() : Menu() {
	subText.setString(" - user mode - ");
	subText.setFont(font);
	subText.setCharacterSize(30);
	subText.setFillColor(sf::Color::White);
	sf::FloatRect managerRect = subText.getLocalBounds();
	subText.setPosition((window.getSize().x - managerRect.width) / 2, (window.getSize().y - managerRect.height) / 2 - 170);

	// 2
	buttonSecond.setString("2. WORD GAME");
	buttonSecond.setFont(font);
	buttonSecond.setCharacterSize(50);
	buttonSecond.setFillColor(sf::Color::White);
	sf::FloatRect buttonSecondRect = buttonSecond.getLocalBounds();        // left                                                  // down
	buttonSecond.setPosition((window.getSize().x - buttonSecondRect.width) / 2, (window.getSize().y - buttonSecondRect.height) / 2 + 10);

	// 3
	buttonThird.setString("3. PROFILE & USERS");
	buttonThird.setFont(font);
	buttonThird.setCharacterSize(50);
	buttonThird.setFillColor(sf::Color::White);
	sf::FloatRect buttonThirdRect = buttonThird.getLocalBounds();        // left                                                  // down
	buttonThird.setPosition((window.getSize().x - buttonThirdRect.width) / 2, (window.getSize().y - buttonThirdRect.height) / 2 + 110);

	window.draw(buttonSecond);
	window.draw(buttonThird);

	u_run();
}

void UserMenu::u_run() {
	while (window.isOpen()) {
		createDisplay();
		createButton();
		handleEvents();
		render();
	}
}

void UserMenu::handleEvents() {
	sf::Event event;
	while (window.pollEvent(event)) {
		sf::Vector2f mousePos(event.mouseButton.x, event.mouseButton.y);
		if (event.type == sf::Event::Closed) {
			window.close();
		}
		else if (event.type == sf::Event::MouseButtonPressed) {
			if (buttonSecond.getGlobalBounds().contains(mousePos)) {
				playClick();
				std::cout << "Second button clicked! Opening new window..." << std::endl;
				window.close();
				GameDisplay gameDisplay;
				gameDisplay.run();
			}
			else if (buttonThird.getGlobalBounds().contains(mousePos)) {
				playClick();
				std::cout << "Third button clicked! Opening new window..." << std::endl;
				window.close();
				CurrentProfile currentProfile; // later must be replaced
				currentProfile.run();
			}
		}
		else if (event.type == sf::Event::MouseMoved) {
			if (buttonFirst.getGlobalBounds().contains(sf::Vector2f(event.mouseMove.x, event.mouseMove.y))) {
				buttonFirst.setFillColor(sf::Color::Red);
			}
			else {
				buttonFirst.setFillColor(sf::Color::White);
			}
			if (buttonSecond.getGlobalBounds().contains(sf::Vector2f(event.mouseMove.x, event.mouseMove.y))) {
				buttonSecond.setFillColor(sf::Color::Red);
			}
			else {
				buttonSecond.setFillColor(sf::Color::White);
			}
			if (buttonThird.getGlobalBounds().contains(sf::Vector2f(event.mouseMove.x, event.mouseMove.y))) {
				buttonThird.setFillColor(sf::Color::Red);
			}
			else {
				buttonThird.setFillColor(sf::Color::White);
			}
		}
	}
}
// menu.h와 .cpp입니다.
#ifndef MENU_H
#define MENU_H

#include "loginSystem.h"
#include "currentProfile.h"

class Menu {
public:
    Menu();
    void run();
    void playClick();

    sf::SoundBuffer clickBuffer;
    sf::Sound clickSound;

    virtual void createDisplay();
    void createButton();
    virtual void handleEvents(); // = 0 해도 결과는 같음(에러)
    void render();

    sf::RenderWindow window;
    sf::Font font;
    sf::Text mainText;
    sf::Text backButton;
    sf::RectangleShape borderRect;
    bool isManager;
    sf::Font m_font;
    sf::Text buttonFirst;
    sf::RectangleShape borderFirst;
};

#endif 
#include "menu.h"

Menu::Menu() : window(sf::VideoMode(1400, 700), "Menu Display") {
}

void Menu::run() {
    while (window.isOpen()) {
        createDisplay();
        createButton();
        handleEvents();
        render();
    }
}

void Menu::createDisplay() {
    if (!font.loadFromFile("font/hangthedj.ttf")) {
        std::cerr << "Failed to load font!" << std::endl;
    }
    mainText.setString("let's practice together");
    mainText.setFont(font);
    mainText.setCharacterSize(70);
    mainText.setFillColor(sf::Color::White);
    sf::FloatRect textRect = mainText.getLocalBounds();
    mainText.setPosition((window.getSize().x - textRect.width) / 2, (window.getSize().y - textRect.height) / 2 - 240);

    // Back button
    backButton.setString("BACK");
    backButton.setFont(font);
    backButton.setCharacterSize(30);
    backButton.setFillColor(sf::Color::White);
    sf::FloatRect loginButtonRect = backButton.getLocalBounds();        // left                                                  // down
    backButton.setPosition((window.getSize().x - loginButtonRect.width) - 250, (window.getSize().y - loginButtonRect.height) / 2 + 180);
    borderRect.setSize(sf::Vector2f(loginButtonRect.width + 10, loginButtonRect.height + 10));
    borderRect.setPosition((window.getSize().x - loginButtonRect.width) - 253, (window.getSize().y - loginButtonRect.height) / 2 + 180);
    borderRect.setFillColor(sf::Color::Transparent);
    borderRect.setOutlineThickness(4);
    borderRect.setOutlineColor(sf::Color::White);
}

void Menu::createButton() {
    if (!m_font.loadFromFile("font/RobotoSlab-Bold.ttf")) {
        std::cerr << "Failed to load font!" << std::endl;
    }
    // 1
    buttonFirst.setString("1. VOCABULARY");
    buttonFirst.setFont(m_font);
    buttonFirst.setCharacterSize(50);
    buttonFirst.setFillColor(sf::Color::White);
    sf::FloatRect buttonFirstRect = buttonFirst.getLocalBounds();        // left                                                 
    buttonFirst.setPosition((window.getSize().x - buttonFirstRect.width) / 2, (window.getSize().y - buttonFirstRect.height) / 2 - 70);
}

void Menu::playClick() {
    if (clickBuffer.loadFromFile("media/click_sound.wav")) {
        clickSound.setBuffer(clickBuffer);
        clickSound.play();
    }
    else {
        std::cerr << "Failed to load click sound file!" << std::endl;
    }
}

void Menu::handleEvents() {
    sf::Event event;
    while (window.pollEvent(event)) {
        sf::Vector2f mousePos(event.mouseButton.x, event.mouseButton.y);
        if (event.type == sf::Event::Closed) {
            window.close();
        }
        else if (event.type == sf::Event::MouseButtonPressed) {
            if (buttonFirst.getGlobalBounds().contains(mousePos)) {
                playClick();
                std::cout << "First button clicked! Opening new window..." << std::endl;
                window.close();
                // insert run
            }
            else if (backButton.getGlobalBounds().contains(mousePos)) {
                playClick();
                std::cout << "BACK button clicked! Opening previous window..." << std::endl;
                window.close();
                LoginSystem loginSystem;
                loginSystem.run();
            }
        }
        else if (event.type == sf::Event::MouseMoved) {
            if (buttonFirst.getGlobalBounds().contains(sf::Vector2f(event.mouseMove.x, event.mouseMove.y))) {
                buttonFirst.setFillColor(sf::Color::Red);
            }
            else {
                buttonFirst.setFillColor(sf::Color::White);
            }
            if (backButton.getGlobalBounds().contains(sf::Vector2f(event.mouseMove.x, event.mouseMove.y))) {
                backButton.setFillColor(sf::Color::Red);
                borderRect.setOutlineColor(sf::Color::Red);
            }
            else {
                backButton.setFillColor(sf::Color::White);
                borderRect.setOutlineColor(sf::Color::White);
            }
        }
    }
}

void Menu::render() {
    window.clear();
    window.draw(mainText);
    window.draw(backButton);
    window.draw(borderRect);
    window.draw(buttonFirst);
    window.draw(borderFirst);
    window.display();
}

답변 1

답변을 작성해보세요.

1

Soobak님의 프로필

Soobak

2023.12.07

안녕하세요, 답변 도우미 Soobak 입니다.

 

강의와 무관한 코드는 질문 답변을 해드리기 어렵습니다.

교수님께서 운영하시는 커뮤니티인, 네이버 카페와 디스코드에서 다른 수강생분들과 질문 답변을 나눠보시는 것을 추천드립니다.


네이버카페 - 홍정모 연구소 (링크)
디스코드 채널 - 홍정모 연구소 (링크)

 

그래도, 저도 공부할 겸 꼼꼼히 읽어보며 도움을 드려보고자 하였으나, 기타 파일들이 없어서 온전히 실행을 할 수 없는 코드라 도움을 드리는 데에 한계가 있네요...

두 에러 중, C3668 'UserMenu::handleEvents': method with override specifier 'override' did not override any base class methods 오류와 관련해서는, Menu 클래스의 handleEvents 멤버 함수가 virtual 로 잘 선언되어 있고, UserMenu 클래스에서 handleEvents 멤버 함수의 정의(반환형, 매개변수 등)도 Menu 클래스의 멤버 함수와 정확히 일치합니다...

따라서, 제 생각에는 C2504 'Menu':base class undefined 에러, 즉, Menu 클래스를 UserMenu 클래스에서 찾을 수 없다는 에러가 문제의 주요 원인 같습니다.

질문자님의 작업 환경을 제가 잘 모르지만, 우선 해당 파일들의 위치와 include 경로를 확인해보시고, 경로도 일치한다면 서로 순환 참조를 하지는 않는지, 각 파일들의 헤더 가드에는 문제가 없는지 확인해보시면 좋을 것 같습니다.

의지님의 프로필

의지

질문자

2023.12.07

정말 죄송합니다. 다음부턴 강의 무관 질문은 하지않도록 조심하겠습니다.

그럼에도 불구하고 도움주신점, 빠르게 답변 해주신점 정말 감사드립니다.

좋은 하루 보내시길 바랍니다:)