marecki Temat założony przez niniejszego użytkownika |
[C++] użycie różnych enum z różnych klas jako argument jednej funkcji zaprzyjaźnionej » 2018-02-06 09:10:05 Stworzyłem poniższy kod. #include <iostream>
using namespace std;
class klasa { public: enum typ { qq, ww, ee }; int tt; friend void foo( klasa::typ sss ); };
class klasa2 { public: enum typ { aa, ss, dd }; friend void foo( klasa2::typ sss ); };
void foo( klasa::typ sss ) { cout << sss << endl; }
void foo( klasa2::typ sss ) { cout << sss << endl; }
int main() { foo( klasa::ww ); foo( klasa2::dd ); return 0; }
Wszystko działa ale chciałbym aby była zadeklarowana jedna funkcja foo, która mogła by przyjmować argument enum z dowolnej klasy, a nie jak powyżej zadeklarowane dwie funkcje dla każdej klasy osobno. Proszę o sugestię jak można to wykonać. |
|
geceves |
» 2018-02-06 09:22:35 Możesz poczytać o szablonach funkcji, jeżeli naprawdę uważasz, że chcesz tak operować.
Wewnątrz funkcji i tak będziesz próbował rozpoznać, który enum przychodzi a nie będziesz w stanie obsługiwać dwóch jednocześnie bo funkcja będzie znała albo jeden albo drugi.
Jak bardzo chcesz to zrobić to możesz rzutować na int i korzystać z offsetu dla rozróżnienia enumów ale to by było mocno niefajne.
Generalnie będzie lepiej jak powiesz, co próbujesz osiągnąć, bo aktualne rozwiązanie: szablony + enum + funkcje zaprzyjaźnione nie wygląda zbyt przyjemnie. |
|
marecki Temat założony przez niniejszego użytkownika |
» 2018-02-06 10:00:26 No właśnie nie chciał bym rozpoznawać w jednej funkcji który enum przychodzi. Chciałbym aby było to robione poprzez odpowiednie wstawienie argumentu.
Nie chcę tworzyć w plikach źródłowych dla klasy 'klasa' i ' klasa2' dwóch tak samo wyglądających funkcji które robiły by dokładnie to samo co mogła by zrobić jedna zadeklarowana w pliku nagłówkowym z deklaracjami klas. |
|
darko202 |
» 2018-02-06 12:02:42 |
|
michal11 |
» 2018-02-06 15:46:53 Tak jak napisał geceves napisz co chcesz zrobić to dostaniesz lepsze odpowiedzi bo w zasadzie odpowiedź na pytanie "jak obsłużyć 2 rożne enumy w jednej funkcji?" już dostałeś, jedynie moge dodać, że możesz sobie napisać jedną funkcję jako implementację i wołać ją w dwóch innych które przyjmują te enumy enum E1 { }; enum E2 { };
namespace details { void funImpl() { } }
void fun1( E1 ) { funImpl(); }
void fun2( E2 ) { funImpl(); }
|
|
marecki Temat założony przez niniejszego użytkownika |
» 2018-02-06 20:27:18 Wklejam kod pliku klasy.h #include <string> #include <windows.h>
using namespace std;
typedef unsigned char byte;
const DWORD DEV1_MEM_LENGTH = 256; const DWORD DEV2_MEM_LENGTH = 58;
class DEVICE1 { private: string name[ DEV1_MEM_LENGTH ]; byte value[ DEV1_MEM_LENGTH ]; public: enum REG { reg1, reg2, reg3 }; public: void showRegister( REG reg ); };
class DEVICE2 { private: string name[ DEV2_MEM_LENGTH ]; byte value[ DEV2_MEM_LENGTH ]; public: enum REG { reg1, reg2, reg3 }; public: void showRegister( REG reg ); };
Natomiast w plikach "DEVICE1.cpp" i "DEVICE2.cpp" jest definicja funkcji void showRegister(REG reg); void DEVICEx::showRegister( REG reg ) { char temp_tab[ 8 ] = { 0 }; byte temp_value = value[ reg ]; for( int i = 0; i < 8; i++ ) { temp_value = value[ reg ] &( 1 << i ); if( temp_value > 0 ) temp_tab[ i ] = '1'; else temp_tab[ i ] = '0'; } cout.width( 12 ); cout << name[ reg ] << " = "; cout.width( 12 ); cout <<( int ) value[ reg ]; cout.width( 12 ); for( int i = 7; i >= 0; i-- ) { cout << temp_tab[ i ] << " "; } cout << endl; }
Nie chcę mieć definicji takiej samej funkcji w każdym pliku cpp i wywoływać ją jako 'showRegister(reg1);'. Chcę mieć jedną w pliku h i wywoływać ją w taki sam sposób. Wykonałem pewną zamianę ale wtedy muszę funkcję wywoływać 'showRegister(value[reg1], name[reg1]);' Próbowałem zrobić to z pomocą funkcji wirtualnej ale nie mogę ponieważ dostaję błędy w stylu 'value' was not declared in this scope class Device { public: void showRegister( REG reg ) { char temp_tab[ 8 ] = { 0 }; byte temp_value = value[ reg ]; for( int i = 0; i < 8; i++ ) { temp_value = value[ reg ] &( 1 << i ); if( temp_value > 0 ) temp_tab[ i ] = '1'; else temp_tab[ i ] = '0'; } cout.width( 12 ); cout << name[ reg ] << " = "; cout.width( 12 ); cout <<( int ) value[ reg ]; cout.width( 12 ); for( int i = 7; i >= 0; i-- ) { cout << temp_tab[ i ] << " "; } cout << endl; }
Najlepiej jak by się dało tak zrobić że jako argument do funkcji przekazuję wskaźnik na obiekt oraz wartość REG z enum ale nie wiem jak to uczynić. |
|
Monika90 |
» 2018-02-06 22:26:43 No to sobie napisz szablon, a jeśli chcesz by miał dostęp do prywatnych składowych to go zaprzyjaźnij. Np. #include <iostream>
using byte = unsigned char;
template < class Device, class Register > void show( const Device & d, Register r ) { std::cout << d.names[ r ] << " = " << + d.registers[ r ] << std::endl; }
class Device1 { public: static constexpr int registers_count = 4; enum Register { r1, r2, r3, r4 }; friend void show <>( const Device1 &, Register ); private: static constexpr const char * names[ registers_count ] = { "r1", "r2", "r3", "r4" }; byte registers[ registers_count ] = { 11, 22, 33, 44 }; };
int main() { Device1 d; show( d, d.r2 ); }
Nie wiem czy o to chodziło... |
|
Monika90 |
» 2018-02-06 22:52:19 Poza tym using namespace std;
typedef unsigned char byte;
Te dwie rzeczy na raz nie przejdą. W przestrzeni std jest zdefiniowany typ byte, więc będzie konflikt. |
|
« 1 » 2 |