Ukazateľ na funkciu, ktorá preberá ako parameter referenciu na odvodenú triedu – C / C++ – Fórum – Programujte.com
 x   TIP: Přetáhni ikonu na hlavní panel pro připnutí webu

Ukazateľ na funkciu, ktorá preberá ako parameter referenciu na odvodenú triedu – C / C++ – Fórum – Programujte.comUkazateľ na funkciu, ktorá preberá ako parameter referenciu na odvodenú triedu – C / C++ – Fórum – Programujte.com

 

Ondrej
~ Anonymní uživatel
156 příspěvků
10. 3. 2021   #1
-
0
-

Ahoj, snažím sa vytvoriť ukazateľ na funkciu, ktorá preberá ako parametre dve referencie na odvodenú triedu. Kedže sa jedná o odvodenú triedu, vytvorím si teda ukazateľ na funkciu ktorej dátové typy parametrov budú referencie na základnú triedu z ktorej bolo dedené.  

Napríklad mám vytvorený dátový typ predstavujúci ukazateľ na funkciu  

typedef bool(*MOT_fptr)(const ColliderMesh::Mesh&, const ColliderMesh::Mesh&)

potom tu mám funkciu, ktorá vracia ukazateľ na funkciu na základe zvoleného typu 

MOT_fptr GetMOT(ColliderMesh::Type type)
{
    switch (type) 
    {
        case ColliderMesh::Type::Rectangle: 
            return &Collider::BoxOverlapTest; // error: return value type does not match the function type
            break;

        case ColliderMesh::Type::Circle:  
            return &Collider::CircleOverlapTest; // error: return value type does not match the function type
            break;

        default: return UNDEF_PTR; 
            break;
    }
}

kde funkcie BoxOverlapTest CircleOverlapTest sú zadeklarované ako

static bool BoxOverlapTest(const ColliderMesh::Rectangle& rect1, const ColliderMesh::Rectangle& rect2);
static bool CircleOverlapTest(const ColliderMesh::Circle& circ1, const ColliderMesh::Circle& circ2);

Obidve triedy ColliderMesh::Rectangle ColliderMesh::Circle sú odvodené zo základnej(rodičovskej) triedy ColliderMesh::Mesh.Avšak pokiaľ sa snažím vrátiť z funkcie GetMOT referenciu na funkciu &Collider::BoxOverlapTest &Collider::Circledostávam chybu return value type does not match the function type.

Otázka teda znie.. je vôbec niečo takéto možné a iba mi niečo uniká, alebo mal by som hľadať iné riešenie ?

Nahlásit jako SPAM
IP: 95.102.89.–
Ondrej
~ Anonymní uživatel
156 příspěvků
10. 3. 2021   #2
-
0
-

#1 Ondrej
Podarilo sa mi to vyriešiť.. v ten moment ma nenapadlo, že môžem funkcie zadeklarovať aby preberali referenciu na triedu z ktorej sa dedí a následne pri predávaní parametrov tejto funkcie iba explicitne zmením dátový typ inštancie odvodenej triedy.

Zmenil som deklaráciu pre funkcie nasledovne 

static bool BoxOverlapTest(const ColliderMesh::Mesh& rect1, const ColliderMesh::Mesh& rect2);
static bool CircleOverlapTest(const ColliderMesh::Mesh& circ1, const ColliderMesh::Mesh& circ2);

a pri volaní týchto funkcií, som im explicitne zmenil dátový typ

auto MOTFunction = Collider::GetMOT(col1MT);
... my code ...
MOTFunction((ColliderMesh::Mesh)col1.m_Mesh[i], (ColliderMesh::Mesh)col2.m_Mesh[j]); // explicitly casting them

niekedy je lepšie si dať pauzu.. v tej chvíli ma to naozaj nenapadlo

Nahlásit jako SPAM
IP: 95.102.89.–
Ondrej
~ Anonymní uživatel
156 příspěvků
10. 3. 2021   #3
-
0
-

#2 Ondrej
A taktiež netuším prečo som vo funkcii GetMOT pri switchi po vrátení hodnoty uvádzal break. Je tam zbytočný

Nahlásit jako SPAM
IP: 95.102.89.–
KIIV
~ Moderátor
+43
God of flame
9. 4. 2021   #4
-
0
-

Nekdo jeste neobjevil polymorfizmus, virtualni metody a interface.

Nasledujici neni moc dobrej napad... Delas vesmes z komara velbouda a pak to predhazujes dal... Jeste se ti tam muze objevit i slicing - kdy ze sveho udelas uplne jinej objekt a pak o kus dal reknes ze ted je to zase komar.. litej... (a ten slicing tam mozna i probiha, jelikoz to predavas do const&)

MOTFunction((ColliderMesh::Mesh)col1.m_Mesh[i], (ColliderMesh::Mesh)col2.m_Mesh[j]);

Nahlásit jako SPAM
IP: 37.48.26.–
Program vždy dělá to co naprogramujete, ne to co chcete...
Staon0
Návštěvník
17. 4. 2021   #5
-
0
-

Pod KIIVovu poznámku "tady ještě někdo neobjevil polymorfismus" bych se jednoznačně podepsal také.

Nicméně k vašim otázkám. Zatímco C++ dokáže automaticky převádět ukazatele a reference na rodičovskou třídu, případně member ukazatele na třídu potomka, tak o parameterech funkce nic takového neplatí. Takže funkce fce(const ColliderMesh::Mesh&) a fce(const ColliderMesh::Circle&) nejsou na sebe konvertibilní, i když v jednom směru by parametry být mohly. Takže odpověď na první otázku je: "ne, není to možné."

Následně jste sjednotil signatury funkcí, čímž bylo možné je vrátit. Potud dobře. Ale z nějakého nejasného důvodu jste překladač nutil explicitně k přetypování. Přitom zde je zrovna to místo, kde překladač umí převést na rodiče sám. Předpokládám, že col1 a col2 jsou něco jako std::vector<ColliderMesh::Circle>, tzn. stačilo zavolat 

MOTFunction(col1.m_Mesh[i], col2.m_Mesh[j]);

protože překladač typ reference převede na rodiče sám.

Tím že jste napsal přetypování na ColliderMesh::Mesh jste navodil KIIVem zmiňovaný slicing - překladač vytvořil dočasnou proměnnou typu ColliderMesh::Mesh, do které překopíroval ze zdrojového objektu col1.m_Mesh[i] pouze tu část odpovídající rodiči ColliderMesh::Mesh, a tento částečný objekt (bez specifické části týkající se ColliderMesh::Circle) poslal jako parametr do funkce. Takže pokud jste si ve funkci parametr přetypoval na Circle, což jste pravděpodobně udělal, tak jste se mohl dost divit.

Všimněte si, že jsem předpokládál, že col1 je typované na konkrétní mesh, nikoliv na společného předka. Pokud je navíc máte jako std::vector<ColliderMesh::Mesh>, tak jste do slicingu zapadl až po hlavu. Všechny prvky v poli totiž obsahují pouze atributy z ColliderMesh::Mesh, bez ohledu na to, jestli jste tam vložil Circle nebo Rectangle.

Nahlásit jako SPAM
IP: 94.113.221.–
Zjistit počet nových příspěvků

Přidej příspěvek

Toto téma je starší jak čtvrt roku – přidej svůj příspěvek jen tehdy, máš-li k tématu opravdu co říct!

Ano, opravdu chci reagovat → zobrazí formulář pro přidání příspěvku

×Vložení zdrojáku

×Vložení obrázku

Vložit URL obrázku Vybrat obrázek na disku
Vlož URL adresu obrázku:
Klikni a vyber obrázek z počítače:

×Vložení videa

Aktuálně jsou podporována videa ze serverů YouTube, Vimeo a Dailymotion.
×
 
Podporujeme Gravatara.
Zadej URL adresu Avatara (40 x 40 px) nebo emailovou adresu pro použití Gravatara.
Email nikam neukládáme, po získání Gravatara je zahozen.
-
Pravidla pro psaní příspěvků, používej diakritiku. ENTER pro nový odstavec, SHIFT + ENTER pro nový řádek.
Sledovat nové příspěvky (pouze pro přihlášené)
Sleduj vlákno a v případě přidání nového příspěvku o tom budeš vědět mezi prvními.
Reaguješ na příspěvek:

Uživatelé prohlížející si toto vlákno

Uživatelé on-line: 0 registrovaných, 10 hostů

Moderátoři diskuze

 

Hostujeme u Českého hostingu       ISSN 1801-1586       ⇡ Nahoru Webtea.cz logo © 20032024 Programujte.com
Zasadilo a pěstuje Webtea.cz, šéfredaktor Lukáš Churý