Panel użytkownika
Nazwa użytkownika:
Hasło:
Nie masz jeszcze konta?

Ambigous base of...

Ostatnio zmodyfikowano 2016-08-19 19:58
Autor Wiadomość
The_Wert
Temat założony przez niniejszego użytkownika
Ambigous base of...
» 2016-08-19 11:19:42
Witam. Uczę się z książki S.Praty "Szkoła Programowania C++". Pod koniec każdego działu są pytania sprawdzające wiedzę i właśnie z jednym z nich mam problem (14 dział, zadanie 4). Oto kod całego programu:

C/C++
#ifndef HEADER_H_
#define HEADER_H_
#include<iostream>
#include<cstdlib>
#include<ctime>

class Person
{
private:
    char * name;
    char * surname;
public:
    Person();
    Person( const char * nm, const char * snm );
    Person( const Person & p );
    virtual ~Person();
    Person & operator =( const Person & p );
    Person * operator =( const Person * p );
    virtual void Show() const;
};


class Gunslinger
    : public Person
{
private:
    int cuts;
    double draw;
public:
    Gunslinger()
        : cuts( 0 )
         , draw( 0 )
    { }
    Gunslinger( const char * nm, const char * snm, int cts, double dw )
        : Person( nm, snm )
         , draw( dw )
         , cuts( cts )
    { }
    Gunslinger( const Person & p, int cts, double dw )
        : Person( p )
         , draw( dw )
         , cuts( cts )
    { }
    virtual double Draw() { return draw; }
    virtual void Show() const;
};

class Card
{
    int x;
    int num;
public:
    Card()
    {
        srand( time( NULL ) );
       
        num =(( std::rand() % 13 ) + 1 );
       
        x =( std::rand() % 2 );
    }
    void show() const
    {
        using std::cout;
       
        cout << "Kolor karty: ";
        if( x == 1 )
             cout << "czerwony\n";
        else if( x == 0 )
             cout << "czarny\n";
       
        cout << "Numer/symbol: ";
       
        if( num == 1 )
             cout << "As\n";
        else if( num == 11 )
             cout << "Walet\n";
        else if( num == 12 )
             cout << "Dama\n";
        else if( num == 13 )
             cout << "Krol\n";
        else
             cout << num << std::endl;
       
    }
};

class PokerPlayer
    : virtual public Person
{
    Card cards;
public:
    PokerPlayer( const char * nm, const char * snm )
        : Person( nm, snm )
         , cards( Card() )
    { }
    PokerPlayer( const Person & p )
        : Person( p )
         , cards( Card() )
    { }
    PokerPlayer( const PokerPlayer & p )
        : Person( p )
    { }
    virtual void Draw() const;
    virtual void Show() const;
};

class BadDude
    : public virtual PokerPlayer
     , public virtual Gunslinger
{
public:
    BadDude( const char * nm, const char * snm, int cts, double dw )
        : PokerPlayer( nm, snm )
         , Gunslinger( nm, snm, cts, dw )
    { }
    BadDude( const Person & p, int cts, double dw )
        : PokerPlayer( p )
         , Gunslinger( p, cts, dw )
    { }
    BadDude( const Gunslinger & g )
        : PokerPlayer( g )
         , Gunslinger( g )
    { }
    BadDude( const PokerPlayer & p, int cts, double dw )
        : PokerPlayer( p )
         , Gunslinger( p, cts, dw )
    { }
    void Gdraw() { Gunslinger::Draw(); }
    void Cdraw() { PokerPlayer::Draw(); }
    virtual void Show() const;
};

#endif // HEADER_H_
[ / cpp ]


C/C++
#include "header.h"
#include <iostream>
#include<cstring>

Person::Person()
{
    name = new char[ 5 ];
    surname = new char[ 5 ];
   
    std::strcpy( name, "Brak" );
    std::strcpy( surname, "Brak" );
}

Person::Person( const char * nm, const char * snm )
{
    name = new char[ std::strlen( nm ) + 1 ];
    std::strcpy( name, nm );
   
    surname = new char[ std::strlen( snm ) + 1 ];
    std::strcpy( surname, snm );
}

Person::Person( const Person & p )
{
    name = new char[ std::strlen( p.name ) + 1 ];
    std::strcpy( name, p.name );
   
    surname = new char[ std::strlen( p.surname ) + 1 ];
    std::strcpy( surname, p.surname );
}

Person::~Person()
{
    delete[] name;
    delete[] surname;
}

Person & Person::operator =( const Person & p )
{
    if( this == & p )
         return * this;
   
    delete[] name;
    name = new char[ std::strlen( p.name ) + 1 ];
    std::strcpy( name, p.name );
   
    delete[] surname;
    surname = new char[ std::strlen( p.surname ) + 1 ];
    std::strcpy( surname, p.surname );
   
    return * this;
}

void Person::Show() const
{
    std::cout << "Imie: " << name << std::endl;
    std::cout << "Nazwisko: " << surname << std::endl;
}


void Gunslinger::Show() const
{
    Person::Show();
    std::cout << "Naciecia na rewolwerze: " << cuts << std::endl;
    std::cout << "Czas wyciagania rewolweru: " << draw << std::endl;
}

void PokerPlayer::Draw() const
{
    cards.show();
}

void PokerPlayer::Show() const
{
    Person::Show();
    Draw();
}

void BadDude::Show() const
{
    Gunslinger::Show();
    PokerPlayer::Draw();
}


Person * Person::operator =( const Person * p )
{
    if( this == p )
         return this;
   
    delete[] name;
    name = new char[ std::strlen( p->name ) + 1 ];
    std::strcpy( name, p->name );
   
    delete[] surname;
    surname = new char[ std::strlen( p->surname ) + 1 ];
    std::strcpy( surname, p->surname );
   
    return this;
}
[ / cpp ]


C/C++
#include<iostream>
#include "header.h"

int main()
{
    using std::cout;
    using std::cin;
    using std::endl;
   
    int lim = 4;
   
    Person * pp[ 4 ];
   
   
   
    for( int i = 0; i < lim; i++ )
    {
        cout << "Podaj imie osoby: ";
        char * temp_n = new char[ 30 ];
        cin.getline( temp_n, 30 );
       
        cout << "Podaj nazwisko osoby: ";
        char * temp_sn = new char[ 30 ];
        cin.getline( temp_sn, 30 );
       
        char ch;
       
        cout << "Wybierz \"zawod\" osoby: ";
        cout << "\n'r' - rewolwerowiec\n";
        cout << "'p' - pokerzysta\n";
        cout << "'o' - oprych\n";
        cout << "'c' - zwykly czlowiek\n";
       
        cin >> ch;
        cin.get();
        switch( ch )
        {
        case 'C':
        case 'c':
            {
                pp[ i ] = new Person( temp_n, temp_sn );
            }
            break;
        case 'O':
        case 'o':
            {
                int cts;
                int drw;
                cout << "Podaj liczbe naciec na rewolwerze: ";
                cin >> cts;
                cout << "Podaj czas wyciagania rewolwera[s]: ";
                cin >> drw;
                cin.get();
                cin.get();
               
                pp[ i ] = new BadDude( temp_n, temp_sn, cts, drw ); //Jeśli z tej linii utworzę komentarz, program działa
            }
            break;
        case 'P':
        case 'p':
            {
                pp[ i ] = new PokerPlayer( temp_n, temp_sn );
            }
            break;
        case 'R':
        case 'r':
            {
                int cts;
                int drw;
                cout << "Podaj liczbe naciec na rewolwerze: ";
                cin >> cts;
                cout << "Podaj czas wyciagania rewolwera[s]: ";
                cin >> drw;
                cin.get();
               
                pp[ i ] = new Gunslinger( temp_n, temp_sn, cts, drw );
            }
            break;
        }
       
        delete[] temp_n;
        delete[] temp_sn;
       
    }
   
    for( int i = 0; i < lim; i++ )
         pp[ i ]->Show();
   
   
   
    cin.get();
   
    return 0;
}
[ / cpp ]

Oto log kompilacji:

||=== Build: Debug in Test 14 dzial zadanie 4 (compiler: GNU GCC Compiler) ===|
E:\Projekty C++\Test 14 dzial\Test 14 dzial zadanie 4\header.h||In constructor 'Gunslinger::Gunslinger(const char*, const char*, int, double)':|
E:\Projekty C++\Test 14 dzial\Test 14 dzial zadanie 4\header.h|27|warning: 'Gunslinger::draw' will be initialized after [-Wreorder]|
E:\Projekty C++\Test 14 dzial\Test 14 dzial zadanie 4\header.h|26|warning:   'int Gunslinger::cuts' [-Wreorder]|
E:\Projekty C++\Test 14 dzial\Test 14 dzial zadanie 4\header.h|30|warning:   when initialized here [-Wreorder]|
E:\Projekty C++\Test 14 dzial\Test 14 dzial zadanie 4\header.h||In constructor 'Gunslinger::Gunslinger(const Person&, int, double)':|
E:\Projekty C++\Test 14 dzial\Test 14 dzial zadanie 4\header.h|27|warning: 'Gunslinger::draw' will be initialized after [-Wreorder]|
E:\Projekty C++\Test 14 dzial\Test 14 dzial zadanie 4\header.h|26|warning:   'int Gunslinger::cuts' [-Wreorder]|
E:\Projekty C++\Test 14 dzial\Test 14 dzial zadanie 4\header.h|31|warning:   when initialized here [-Wreorder]|
E:\Projekty C++\Test 14 dzial\Test 14 dzial zadanie 4\program.cpp||In function 'int main()':|
E:\Projekty C++\Test 14 dzial\Test 14 dzial zadanie 4\program.cpp|56|error: 'Person' is an ambiguous base of 'BadDude'|
||=== Build failed: 1 error(s), 6 warning(s) (0 minute(s), 0 second(s)) ===|


Byłbym bardzo wdzięczny, gdybyście pomogli mi naprawić ten program, aby działał prawidłowo, ewentualnie dali jakieś rady jak lepiej pisać kod. Z góry dziękuję za odpowiedź.
P-150984
pekfos
» 2016-08-19 18:12:06
Dziedziczenie wirtualne jest w złych miejscach. Tu masz przykład:
» Programowanie obiektowe, C++ » PolimorfizmDziedziczenie wirtualne lekcja
P-150993
The_Wert
Temat założony przez niniejszego użytkownika
» 2016-08-19 19:58:42
Dziękuję Ci bardzo;) Miałeś rację, wystarczyło ustawienie w klasie Gunslinger wirtualnego dziedziczenia po klasie Person. Temat zamykam.
P-150994
« 1 »
  Strona 1 z 1