Avatar billede lars314 Nybegynder
15. september 2005 - 09:05 Der er 10 kommentarer og
1 løsning

Hvorfor får jeg ingen compiler warning?

Nedenfor er der 2 kode eksempler. Jeg synes at jeg burde få en warning når jeg kompilerer det første eksempel.
Hvad er det jeg lige har overset?
Hvorfor give det første eksempel ingen warning?

Compiler: Borland CBuilder6

Kode eksempel 1:

//---------------------------------------------------------------------------
#include <iostream>

class A
{
    public:
        A() {}
        A(const A&) {}
        virtual ~A() {}
        A& operator=(const A&) {return *this;}

        void f()
        {std::cout << "A::f" << std::endl;}
};

class B : public A
{
    public:
        B() {}
        B(const B& b) : A(b) {}
        virtual ~B() {}
        B& operator=(const B& b) {A::operator=(b); return *this;}

        void f()
        {std::cout << "B::f" << std::endl;}
};

int main(int argc, char* argv[])
{
    A a;
    B b;

    a.f();
    b.f();

    A& ar = b;
    ar.f();
   
    return 0;
}
//---------------------------------------------------------------------------

Hvis jeg compiler dette får jeg ingen warnings.
Output bliver:
A::f
B::f
A::f (Arrg, bang jeg er død)


Kode eksempel 2: (samme som før men A::f er virtual)

//---------------------------------------------------------------------------
#include <iostream>

class A
{
    public:
        A() {}
        A(const A&) {}
        virtual ~A() {}
        A& operator=(const A&) {return *this;}

        virtual void f()
        {std::cout << "A::f" << std::endl;}
};

class B : public A
{
    public:
        B() {}
        B(const B& b) : A(b) {}
        virtual ~B() {}
        B& operator=(const B& b) {A::operator=(b); return *this;}

        void f()
        {std::cout << "B::f" << std::endl;}
};

int main(int argc, char* argv[])
{
    A a;
    B b;

    a.f();
    b.f();

    A& ar = b;
    ar.f();
   
    return 0;
}
//---------------------------------------------------------------------------

Output bliver:
A::f
B::f
B::f (det var meget bedre!)
Avatar billede arne_v Ekspert
15. september 2005 - 09:18 #1
hvorfor skulle det give en warning ?

sådan virker ikke virtual metoder !
Avatar billede arne_v Ekspert
15. september 2005 - 09:19 #2
konklusionen er åbenlys: vær gavmild med virtual keywordet !
Avatar billede lars314 Nybegynder
15. september 2005 - 09:49 #3
Jeg synes den burde give en warning fordi det er en potentiel fejl fra programmørens side, lige så vel som if(a = 1) giver en warning.

Jeg er lidt imod at erklærer alle funktioner for virtuelle, hvis ikke de behøver at være det. Der er et teoretisk tab af performance ved at gøre det.
http://www.research.att.com/~bs/bs_faq2.html#virtual
http://www.parashift.com/c++-faq-lite/virtual-functions.html#faq-20.3
Jeg ende jo nok med at måtte gøre det, da min compiler jo åbenbart ikke har tænkt sig at være hjælpsom mht det problem.
Avatar billede arne_v Ekspert
15. september 2005 - 10:41 #4
det kan jeg ikke se

det kunne jo lige så godt være en potentiel fejl at sætte virtual på

det er 2 forskellige behaviours - der er ikke en "rigtig" og en "forkert"

C# har løst problemet ved at man skal skrive eksplicit override eller new
i sub klassen

med hensyn til performance tab ved virtual så er det efter min mening et levn
fra for 15 år siden
Avatar billede lars314 Nybegynder
15. september 2005 - 10:57 #5
if(a = b)
{
...
}
er jo heller ikke en fejl eller nødvendigvis forkert, men det generer da en warning.

Jeg kan ikke se hvordan det at sætte et virtual på kan være en potentiel fejl, især ikke hvis man arbejder på objekter gennem pointere eller referencer til deres base-klasser.
Avatar billede arne_v Ekspert
15. september 2005 - 11:04 #6
if(a = b)

er enten en fejl eller bad coding practice

----

hvis en metode ikke skal være virtual så er det jo en fejl hvis der er virtual på
Avatar billede lars314 Nybegynder
15. september 2005 - 11:25 #7
Jeg synes også at if(a=b) er bad coding practice, men det synes jeg faktisk også mit første kode eksempel er.
Nå men det lader jo til at de gode folk hos Borland er enige med dig og ikke mig. Så jeg må vist leve med det.

Pokkers, jeg har lige ryddet op i virtual erklæringerne i det mellem store (50 klocs) projekt jeg har gang i, nu må jeg vist til at sætte dem ind igen (med lidt ekstra for en sikkerheds skyld).

Jeg har sadt meget pris på denne lille diskussion. Jeg lader den lige stå åben til i morgen. Hvis der til den tid ikke er sket noget videre, så smid lige et svar i hvis du vil have de 15 point.
Avatar billede arne_v Ekspert
15. september 2005 - 21:50 #8
andre compilere giver heller ikke warning på den

jeg har testet med GCC og MSVC++ og DEC C++

ingen af dem gav warnings
Avatar billede arne_v Ekspert
15. september 2005 - 21:51 #9
og et svar
Avatar billede lars314 Nybegynder
16. september 2005 - 09:22 #10
Nu fandt jeg problematikken i "C++ Gotchas", den har nummer 71 "Hiding Nonvirtual Functions".

"Hiding a base class nonvirtual function raises the complexity of using a hierarchy without providing any compensating merit"

Så det er bestemt ikke smart at gøre.

"C++ Gotchas" (ISBN 0-321-12518-5) er en ganske udemærket bog at have. Ikke helt på højde med "C++ FAQs" (ISBN 0-201-30983-1) men tæt på.
Avatar billede arne_v Ekspert
16. september 2005 - 10:56 #11
som sagt har C# en pæn løsning idet man i sub klassen skal angive override eller
new alt efter hvad man vil
Avatar billede Ny bruger Nybegynder

Din løsning...

Tilladte BB-code-tags: [b]fed[/b] [i]kursiv[/i] [u]understreget[/u] Web- og emailadresser omdannes automatisk til links. Der sættes "nofollow" på alle links.

Loading billede Opret Preview
Kategori
Kurser inden for grundlæggende programmering

Log ind eller opret profil

Hov!

For at kunne deltage på Computerworld Eksperten skal du være logget ind.

Det er heldigvis nemt at oprette en bruger: Det tager to minutter og du kan vælge at bruge enten e-mail, Facebook eller Google som login.

Du kan også logge ind via nedenstående tjenester