Kirjautuminen

Haku

Tehtävät

Keskustelu: Ohjelmointikysymykset: C++: Funktio osoitin tuntemattoman luokan metodiin

Oskuz [01.11.2014 18:15:02]

#

Eli miten luodaan funktio-osoitin joka hyväksyy sellaistenkin luokkien metodit joita ei ole vielä siihen mennessä määritelty/esitelty esimerkkitilanne (ei toimi):
foo.hpp

#ifndef  _foo_hpp_
#define  _foo_hpp_ 1

typedef bool F (int);

class foo{
	int a;
	public:
		foo(int a_): a(a_){
		}
		bool tarkista(F f){
		return f(this->a);
		}
};


#endif

main.c

#include <iostream>
#include "foo.hpp"


class bar{
	int c= 5;
	public:
	bool suurempi(int b){
			return b > c;
		}
};

int main(){
	foo Foo(6);
	bar Bar;
	std::cout<<Foo.tarkista(Bar.suurempi)<<std::endl;
}

Vai olisiko tähän parempia tapoja? Kuten esim. template?

Metabolix [01.11.2014 18:38:42]

#

Eihän tuollainen koodi edes läheskään käänny. Määrittelemäsi tyyppi F on osoitin funktioon, ei jäseneen. Edes oikean jäsenosoittimen avulla et pysty kutsumaan tietyn olion tiettyä jäsentä, koska funktio-osoitin ei sisällä tietoa oliosta. Tarvitsisit erikseen osoittimen olioon ja osoittimen funktioon, ja lisäksi kutsupaikalla pitäisi tietää luokasta, jotta kutsu tapahtuisi oikein (erityisesti virtuaalisesti periytettyjen luokkien kohdalla).

Käyttämäsi nimet ovat kieroutuneita: jos isoja kirjaimia käytetään, niitä käytetään lähes järjestään ensin luokkien nimissä ja harvemmin muuttujissa. Yleensä siis luokka olisi Foo ja muuttuja foo eikä päinvastoin.

Järkevin ratkaisu ongelmaasi on nyt joka tapauksessa C++11:n funktio-objektien käyttö:

#include <functional>
#include <iostream>
struct A {
	int i;
	bool tarkista(std::function<bool(int)> f) const {
		return f(i);
	}
};
struct B {
	int i;
	bool suurempi(int j) const {
		return i > j;
	}
};
int main() {
	A a = {1};
	B b = {2};
	std::function<int(bool)> f = std::bind(&B::suurempi, b, std::placeholders::_1);
	std::cout << f(a.i) << std::endl; // b.suurempi(a.i)
	std::cout << a.tarkista(f) << std::endl; // tavallaan a.tarkista(b.suurempi)
}

Vastaus

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

Tietoa sivustosta