Kirjautuminen

Haku

Tehtävät

Keskustelu: Ohjelmointikysymykset: C++: error: ‘funktio’ was not declared in this scope

Sivun loppuun

Mitjander [15.08.2011 20:37:58]

#

Hei, olen tässä aikani pähkäillyt miksi ihmeessä koodini ei toimi. Olen tehnyt ohjelmaani varten Menu-luokan jolla voi tehdä helposti pää- ja pause-valikot. Funktio jolla lisätään valinta valikkoon pyytää painikkeen kuvat ja osoittimen funktioon joka suoritetaan nappia painettaessa. Jostain syystä tulee tämän lainen virhe käännettäessä:

main.cpp:16:49: error: ‘Menuf’ was not declared in this scope

Koodi jota olen yrittänyt saada toimimaan: (main.cpp)

#include <SFML/Window.hpp>    //Liitetään tarvittavat kirjastot
#include <SFML/Graphics.hpp>
#include "Menu.hpp"           //Myös oma "Menu" luokka

bool Menuf(void);             //Esitellään funktio joka suoritetaan jos painiketta valikossa painetaan

int main()
{
    sf::Image redButton;    //Ladataan painikkeen kuvat
    sf::Image greenButton;
    redButton.LoadFromFile("rb.png");
    greenButton.LoadFromFile("gb.png");
    sf::RenderWindow App(sf::VideoMode(800, 600, 32), "Scape War");    //Avataan ikkuna
    const sf::Input& Input = App.GetInput();
    Menu MainMenu(true);	                           //Luodaat valikko
    MainMenu.add_button(redButton, greenButton, Menuf);    //Lisätään painike
    while (App.IsOpened())
    {
        sf::Event Event;
        while (App.GetEvent(Event))   //Käydään kaikki tapahtumat läpi
        {
            if (Event.Type == sf::Event::Closed)   //Suljetaan jos käyttäjä tahtoo
                App.Close();
            if ((Event.Type == sf::Event::KeyPressed) && (Event.Key.Code == sf::Key::Escape))    //ESC:istäkin voi poistua
                App.Close();
        }
	MainMenu.update(&App, 800, 600);   //Päivitetään valikko ruudulle
        App.Display();                     //Päivitetään ruutu
    }
    return EXIT_SUCCESS;
}

bool Menuf(void) {    //Tässä sisältöä tälle funktiolle
    return true;      //Eli ei tee juuri mitään.
}

Teuro [15.08.2011 20:46:04]

#

Kerrotko vielä miksi Menuf-funktio on kirjoitettu? Sehän ei oman kuvauksesi mukaankaan tee mitään.

Metabolix [15.08.2011 20:46:54]

#

Katsoitko edes virheen rivinumeroa? Ei se taida tuossa koodissa olla vaan Menu.hpp:ssä. Sieltähän et voi Menuf-funktioon tuolla nimellä suoraan viitata.

Mitjander [15.08.2011 21:07:28]

#

Joo viheen rivinumero tosta unohtuikin(päivitin ekaan viestiin). Kyllä, se näyttää olevan tossa tiedostossa(main.cpp), tuossa kohdassa missä se annetaan parametriksi Menu-luokan funktiolle. Menuf funktio on testaamista varten, halusin testata Menu-luokan toimintaa. Peli on vasta niin alussa että sen ei ole tarkoitus tehdä mitään muuta, kuin näytää valikko. Jonkin lainen funktio oli kyhättävä, koska sitä parametriksi tarvitaan. En ole yrittänyt Menuf-funktioon viitata muissa tiedostoissa.

vesikuusi [15.08.2011 21:40:12]

#

Siis tuolla rivillä 16 annat funktion parametrina? Ehkä tarkoitat lähettää sen paluuarvon, kirjoita sulkeet perään. Nythän siinä lukee vain "Menuf", kirjoita "Menuf()".

Mitjander [15.08.2011 22:07:11]

#

Jos ohjelmassa kutsuttaisiin Menuf:ää normaalisti ("Menuf();") tulee yhä tuo virheilmoitus. :/ Siis tarkoitus on että tuo Menu-luokka voi milloin haluaa kutsua sille parametrina annetun funktio-osoittimen kautta Mainf funktiota.
Menu.hpp:ssä tuo funktio jolle funktio-osoitin halutaan antaa on esitelty seuraavati:

int add_button(sf::Image img, void (*onClick)(void));
int add_button(sf::Image  img, sf::Image img2, void (*onClick)(void));

ja Menu.cpp:ssä:

int Menu::add_button(sf::Image img, void (*onClick)(void)){
	ButtonImage.push_back(img);
	ButtonImage2.push_back(img);
	ButtonFunction.push_back(*onClick);
	ButtonMode.push_back(0);
}

int Menu::add_button(sf::Image img, sf::Image img2, void (*onClick)(void)){
	ButtonImage.push_back(img);
	ButtonImage2.push_back(img2);
	ButtonFunction.push_back(*onClick);
	ButtonMode.push_back(0);
}

vesikuusi [15.08.2011 22:15:36]

#

Joo, mutta eihän tuossa rivillä 16 mitään funktio-osoitinta lähetetä? Sanokaa, jos olen väärässä, mutta minusta nyt näyttää siltä. Eikös funktio-osoitin pitäisi luoda erikseen? Minusta näyttää, että kirjoitat vain funktion nimen ilman sulkeita. Tee funktio-osoitin, joka osoittaa Menuf-funktioon ja lähetä se add_buttonille. Tämän enempää en osaa nyt auttaa :)

Metabolix [15.08.2011 22:26:12]

#

Funktiosi paluuarvo on bool, se ei siis sovi tuohon parametriin. Ja vesikuusi on väärässä, osoitin menee juuri noin.

Parametrilistan paikalla oleva void on turha tässä kielessä.

vesikuusi [15.08.2011 22:30:48]

#

Aivan, itse en tota huomannutkaan! Kiitti Metabolix, opin taas jotain uutta :D

Mitjander [16.08.2011 10:21:37]

#

Korjasin Menuf-funktion näin:

void Menuf(){
	return;
}

Ja tulee virheilmoituksia:

Menu.hpp:9:1: error: new types may not be defined in a return type
Menu.hpp:9:1: note: (perhaps a semicolon is missing after the definition of ‘Menu’)
main.cpp:5:12: error: two or more data types in declaration of ‘Menuf’
main.cpp: In function ‘int main()’:
main.cpp:18:49: error: ‘Menuf’ was not declared in this sc

Menu.hpp kokonaisuudessaan:

#include <SFML/Window.hpp>
#include <SFML/Graphics.hpp>
#include <vector>

#ifndef _MENU_HPP
#define _MENU_HPP 1
typedef void (*IPF)();

class Menu{
public:
	Menu(bool parrow_keys);
	int add_button(sf::Image img, void (*onClick)());
	int add_button(sf::Image  img, sf::Image img2, void (*onClick)());
	int get_button_mode(int button_no);
	void update(sf::RenderWindow*, int, int);
private:
	std::vector <sf::Image> ButtonImage;
	std::vector <sf::Image> ButtonImage2;
	std::vector <int> ButtonMode;
	std::vector <IPF> ButtonFunction;
	bool arrow_keys;
}

#endif

ja Menu.cpp:

#include "Menu.hpp"
#include <SFML/Window.hpp>
#include <SFML/Graphics.hpp>
#include <vector>

Menu::Menu(bool parrow_keys){
	arrow_keys = parrow_keys
}

int Menu::add_button(sf::Image img, void (*onClick)(void)){
	ButtonImage.push_back(img);
	ButtonImage2.push_back(img);
	ButtonFunction.push_back(*onClick);
	ButtonMode.push_back(0);
}

int Menu::add_button(sf::Image img, sf::Image img2, void (*onClick)()){
	ButtonImage.push_back(img);
	ButtonImage2.push_back(img2);
	ButtonFunction.push_back(*onClick);
	ButtonMode.push_back(0);
}

int Menu::get_button_mode(int button_no){
	return ButtonMode[button_no];
}

void Menu::update(sf::RenderWindow* app, int w, int h){
	sf:Sprite button;
	sf:Input& Input = app.GetInput();
	int mouseX = Input.GetMouseX();
	int mouseY = Input.GetMouseY();
	for(int i = 0; i < ButtonMode.size(); i++){
		if(ButtonMode[i] == 0){
			button.Set_Image(ButtonImage[i]);
		} else if(ButtonMode[i] == 1){
			button.Set_Image(ButtonImage1[i]);
		}
		button.SetX(w/2-button.GetImage().GetWidth()/2);
		int yhtl = 0;
		for(int ii = 0; ii < ButtonMode.size(); ii++){
			yhtl = yhtl + ButtonImage[i].GetHeight();
		}
		button.SetY(h/ButtonMode.size()-yhtl/ButtonMode.size());
		if(mouseX > w/2-button.GetImage().GetWidth()/2 and mouseX < w/2-button.GetImage().GetWidth()/2+button.GetImage().GetWidth()){
			if(mouseY > h/ButtonMode.size()-yhtl/ButtonMode.size() and mouseY < h/ButtonMode.size()-yhtl/ButtonMode.size()+button.GetImage().GetHeight()){
				ButtonMode[i] = 1
				if(Input.IsMouseButtonDown(sf::Mouse::Right);)
					ButtonFunction[i]();
			} else{
				ButtonMode[i] = 0
			}
		} else{
			ButtonMode[i] = 0
		}
		app.Draw(button);

	}
}

Deffi [16.08.2011 10:52:24]

#

Menu.hpp:n riviltä 22 puuttuu puolipiste sulkevan aaltosulun jälkeen, aivan kuten virheilmoitus vihjaa. Tämä selittää myös miksi Menuf-funktiota ei löydy.

Mitjander [16.08.2011 11:58:06]

#

/tmp/ccsT4lpt.o: In function `main':
main.cpp:(.text+0x210): undefined reference to `Menu::Menu(bool)'
main.cpp:(.text+0x271): undefined reference to `Menu::add_button(sf::Image, sf::Image, void (*)())'
main.cpp:(.text+0x313): undefined reference to `Menu::update(sf::RenderWindow*, int, int)'
collect2: ld returned 1 exit status

Mitäs nyt? Ensimmäinen ohjelma jota yritän linux koneella saada aikaiseksi niin on vähän ongelmia, kun komentoriviltä pitää kääntää ja muuta. .o on ilmeisesti vastaava kuin .dll?

Metabolix [16.08.2011 12:08:46]

#

Nyt et ole kääntänyt kuin yhden tiedoston. Ei siitä kokonaista ohjelmaa synny. Asialla ei myöskään ole mitään tekemistä dll:n tai Linuxin vastaavan (so:n) kanssa.

Voit kääntää kaikki cpp-tiedostot kerralla, tai voit kääntää kunkin cpp-tiedoston erikseen ja linkittää objektit lopuksi yhteen.

g++ a.cpp b.cpp -o ohjelma
# Tai: g++ *.cpp -o ohjelma
g++ -c a.cpp -o a.cpp.o
g++ -c b.cpp -o b.cpp.o
g++ a.cpp.o b.cpp.o -o ohjelma

Jälkimmäisen tavan etuna on, että ei tarvitse kääntää aina uudestaan kaikkia tiedostoja vaan vain muuttuneet. Automaattista käännöstä varten voit tehdä Makefilen, joka sisältää listan tiedostoista ja yleiset säännöt niiden käsittelyyn.

Mitjander [16.08.2011 15:36:22]

#

Sain käännettyä, mutta nyt kun ajan ohjelman ja se näyttää tältä: http://img193.imageshack.us/img193/8872/ihmenappi.png
Tuo "nappi" menee joka suoritus kerralla huonommaksi ja vaihtaa paikkaa.

(Mod. huom: Kannattaa vähän katsoakin, mitä niistä muotoilun apunapeista viestiin tulee. Suora linkki ei vaadi tageja.)


Sivun alkuun

Vastaus

Aihe on jo aika vanha, joten et voi enää vastata siihen.

Tietoa sivustosta