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

Dyskusja na temat zmiennej globalnej i singletona

Ostatnio zmodyfikowano 2015-06-10 14:40
Autor Wiadomość
jankustosz
Temat założony przez niniejszego użytkownika
Dyskusja na temat zmiennej globalnej i singletona
» 2015-06-08 14:24:12
C/C++
vector < Element *> elementy;

Element::Element()
{
    el = NULL;
    elementy.push_back( this );
    string s;
    stringstream ss;
    ss << elementy.size();
    ss >> s;
    komunikat( WinApiNULL, s.c_str(), "dodaje", MB_OK | MB_ICONINFORMATION );
}

void Font::UstawNaWszystkieElementy()
{
    string s;
    stringstream ss;
    ss << elementy.size();
    ss >> s;
    komunikat( WinApiNULL, "Oto rozmiar vectora :(", s.c_str(), MB_OK );
   
    for( int i = 0; i < elementy.size(); i++ )
    {
        UstawNaElement( * elementy[ i ] );
    }
}
.
Wiem że decydując się na dodawanie w konstruktorze muszę uważać żeby funkcje nie robiły kopi klasy Elementy. Zawsze wysyłane są wskaźniki lub referencje.
W głównej funkcji programu zrobiłem 4 objekty klasy Elementy i 4 razy pokazał się komunikat z liczbami kolejno 1 2 3 4.
Później jest wywołana metoda UstawNaWszystkieElementy() i niemożliwe pokazuje że elementy.size() jest równe 0 i ani razu nie wchodzi w pętle. Najgorsze jest to że kompilator nie pokazuje ani jednego ostrzeżenia.
PS Nie zwracajcie uwagi na moje funkcje typu komunikat zapewniam was że robią co mają robić.
Może dodam jeszcze że mam 3 pliki main.cpp WinApi.h i WinApi.cpp. Ten kod znajduje sie w WinApi.cpp
P-133321
pekfos
» 2015-06-08 15:06:41
Zmienna globalna to słaby pomysł. Gdzie to wywołujesz? To wszystkie odwołania do elementy?
P-133323
jankustosz
Temat założony przez niniejszego użytkownika
To jest cały kod jeżeli chcesz. Ja pokazałem tylko to w czym jest problem.
» 2015-06-08 19:39:29
Jak co to dopiero się uczę, wczoraj przerobiłem kontrolki. Nie mówcie mi o tym że coś mogłoby się inaczej nazywać. Piszcie tylko jeżeli wiecie dlaczego metoda UstawNaWszystkieElementy() nie działa jak trzeba.
PS Korzystam z visual studio.


=======================================WinApi.h=======================================
C/C++
#pragma once
#include <windows.h>
#include <string>
#include <Windowsx.h>
#include <vector>


#define Wmain() int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow)
#define WinApiNULL Element(false)


using std::string;
using std::vector;


class Element
{
    WNDCLASSEX wc;
    HWND el;
public:
    void operator =( Element & ele );
    bool operator !();
    bool operator ==( bool jak );
    bool operator ==( LPARAM lParm );
    friend bool operator ==( LPARAM lParm, Element & ele );
    friend int komunikat( Element & okno, LPCSTR text, LPCSTR title, UINT style );
    Element( bool dodac = true );
    void wyswietl();
    void StworzWinClass( HINSTANCE hInstance, LPCSTR nazwa_klasy, WNDPROC winproc, UINT styl, HICON ikona_okien, HICON mala_ikona, HCURSOR kursor, HBRUSH kolor, LPCTSTR menu = 0 );
    void StworzObjekt( DWORD rozszerzony_styl, LPCSTR nazwa_klasy, LPCSTR title, DWORD podstawowy_styl, INT szerokosc, INT wysokosc, HINSTANCE hInstance, INT x = CW_USEDEFAULT, INT y = CW_USEDEFAULT, Element & glowne_okno = WinApiNULL, HMENU menu = 0, LPVOID dodatkowe_parametry = 0 );
    void SetText( string s );
    string getText();
    void wyslij_message( UINT rodzaj, WPARAM wParam, char * lParam );
    void CheckBoxZmienStan( bool tryb );
    bool CheckBoxStan();
    int ComboBoxWybrano();
    string ComboBoxGetText();
    int ComboBoxGetLenght();
    void RadioButtonZaznacz( int odkad, int dokad, int wybierz );
};


class Msg
{
    MSG Komunikat;
public:
    BOOL pobiez();
    void wyslij();
    WPARAM returnuj();
};

//Font

class Font
{
    HFONT font;
public:
    Font();
    void UstawNaElement( Element & ele );
    void UstawNaWszystkieElementy();
};


=======================================WinApi.cpp=======================================
C/C++
#include "WinApi.h"
#include <string>
#include <Windowsx.h>
#include <vector>
#include <sstream>
//Okno

using std::string;
using std::vector;
using std::stringstream;

vector < Element *> elementy;

int komunikat( Element & okno, LPCSTR text, LPCSTR title, UINT style )
{
    return MessageBox( okno.el, text, title, style );
}

void Element::operator =( Element & ele )
{
    el = ele.el;
}

bool Element::operator !()
{
    return !el;
}
bool Element::operator ==( bool jak )
{
    return !el == !jak;
}
bool Element::operator ==( LPARAM lParm )
{
    return( el ==( HWND ) lParm );
}

bool operator ==( LPARAM lParm, Element & ele )
{
    return(( HWND ) lParm == ele.el );
}

Element::Element( bool dodac )
{
    el = NULL;
    if( dodac )
    {
        elementy.push_back( this );
        string s;
        stringstream ss;
        ss << elementy.size();
        ss >> s;
        komunikat( WinApiNULL, s.c_str(), "dodaje", MB_OK | MB_ICONINFORMATION );
    }
}

void Element::StworzWinClass( HINSTANCE hInstance, LPCSTR nazwa_klasy, WNDPROC winproc, UINT styl, HICON ikona_okien, HICON mala_ikona, HCURSOR kursor, HBRUSH kolor, LPCTSTR menu )
{
    wc.hInstance = hInstance;
    wc.lpszClassName = nazwa_klasy;
    wc.lpfnWndProc = winproc;
    wc.style = styl;
    wc.cbSize = sizeof( WNDCLASSEX );
    wc.hIcon = ikona_okien;
    wc.hIconSm = mala_ikona;
    wc.hCursor = kursor;
    wc.lpszMenuName = menu;
    wc.hbrBackground = kolor;
    wc.cbWndExtra = 0;
    wc.cbClsExtra = 0;
    if( !RegisterClassEx( & wc ) )
    {
        komunikat( WinApiNULL, "Nieprawidłowa klasa okna!", "Problem!", MB_OK | MB_ICONERROR );
        exit( 1 );
    }
}

void Element::StworzObjekt( DWORD rozszerzony_styl, LPCSTR nazwa_klasy, LPCSTR title, DWORD podstawowy_styl, INT szerokosc, INT wysokosc, HINSTANCE hInstance, INT x, INT y, Element & glowne_okno, HMENU menu, LPVOID dodatkowe_parametry )
{
    el = CreateWindowEx( rozszerzony_styl, nazwa_klasy, title, podstawowy_styl, x, y, szerokosc, wysokosc, glowne_okno.el, menu, hInstance, dodatkowe_parametry );
    if( el == NULL )
    {
        string tmp = title;
        komunikat( WinApiNULL,( "Objekt <" + tmp + "> odmówił przyjścia na świat!" ).c_str(), "Problem!", MB_OK | MB_ICONERROR );
        exit( 1 );
    }
}
void Element::wyswietl()
{
    ShowWindow( el, SW_SHOW );
    UpdateWindow( el );
}

void Element::SetText( string s )
{
    SetWindowText( el, s.c_str() );
}

string Element::getText()
{
    DWORD dlugosc = GetWindowTextLength( el );
    LPSTR Bufor =( LPSTR ) GlobalAlloc( GPTR, dlugosc + 1 );
    GetWindowText( el, Bufor, dlugosc + 1 );
    string * s = new string;
    * s = Bufor;
    GlobalFree( Bufor );
    return * s;
}

void Element::wyslij_message( UINT rodzaj, WPARAM wParam, char * lParam )
{
    SendMessage( el, rodzaj, wParam,( LPARAM ) lParam );
}

void Element::CheckBoxZmienStan( bool tryb )
{
    int id = GetDlgCtrlID( el );
    if( tryb )
         CheckDlgButton( el, id, BST_CHECKED );
    else if( !tryb )
         CheckDlgButton( el, id, BST_UNCHECKED );
   
}
bool Element::CheckBoxStan()
{
    int id = GetDlgCtrlID( el );
    return( IsDlgButtonChecked( el, id ) == BST_CHECKED );
}

int Element::ComboBoxWybrano()
{
    return ComboBox_GetCurSel( el );
}
string Element::ComboBoxGetText()
{
    int dlugosc = ComboBox_GetTextLength( el );
    LPSTR NapisZcomboBoxa =( LPSTR ) GlobalAlloc( GPTR, dlugosc + 1 );
    ComboBox_GetText( el, NapisZcomboBoxa, dlugosc + 1 );
    string * s = new string;
    * s = NapisZcomboBoxa;
    return * s;
}
int Element::ComboBoxGetLenght()
{
    return ComboBox_GetTextLength( el );
}

void Element::RadioButtonZaznacz( int odkad, int dokad, int wybierz )
{
    CheckRadioButton( el, odkad, dokad, wybierz );
}
//Msg

BOOL Msg::pobiez()
{
    return GetMessage( & Komunikat, NULL, 0, 0 );
}

void Msg::wyslij()
{
    TranslateMessage( & Komunikat );
    DispatchMessage( & Komunikat );
}
WPARAM Msg::returnuj()
{
    return Komunikat.wParam;
}

//Font
Font::Font()
{
    font =( HFONT ) GetStockObject( DEFAULT_GUI_FONT );
}

void Font::UstawNaElement( Element & ele )
{
    ele.wyslij_message( WM_SETFONT,( WPARAM ) font, 0 );
}

void Font::UstawNaWszystkieElementy()
{
    string s;
    stringstream ss;
    ss << elementy.size();
    ss >> s;
    komunikat( WinApiNULL, "Oto rozmiar vectora :(", s.c_str(), MB_OK );
   
    for( int i = 0; i < elementy.size(); i++ )
    {
        UstawNaElement( * elementy[ i ] );
    }
}


=======================================main.cpp=======================================
C/C++
#include "WinApi.h"
#include <Windows.h>

LRESULT CALLBACK WndProc( HWND hwnd, UINT msg, WPARAM wPar, LPARAM lPar );

Element okno;
Element CheckBox1;
Element lista;
Wmain()
{
    int const X = 800, Y = 600;
    okno.StworzWinClass( hInstance, "glowanaklasa", WndProc, CS_DROPSHADOW, LoadIcon( 0, IDI_APPLICATION ), LoadIcon( 0, IDI_APPLICATION ), LoadCursor( 0, IDC_ARROW ),( HBRUSH ) GetStockObject( WHITE_BRUSH ) );
    okno.StworzObjekt( WS_EX_CLIENTEDGE, "glowanaklasa", "tytuloknona", WS_CAPTION | WS_SYSMENU | WS_MINIMIZEBOX, 800, 600, hInstance );
   
    CheckBox1.StworzObjekt( WS_EX_CLIENTEDGE, "BUTTON", "test", WS_CHILD | WS_VISIBLE | BS_CHECKBOX, 200, 25, hInstance, 300, 470, okno );
    lista.StworzObjekt( WS_EX_CLIENTEDGE, "COMBOBOX", NULL, WS_CHILD | WS_VISIBLE | WS_BORDER | CBS_DROPDOWN, 700, 400, hInstance, 40, 50, okno );
    lista.wyslij_message( CB_ADDSTRING, 0, "Magiczne uderzenie" );
    lista.wyslij_message( CB_ADDSTRING, 0, "Zwykły strzał" );
   
   
    Font font;
    font.UstawNaWszystkieElementy();
   
    okno.wyswietl();
    Msg m;
    while( m.pobiez() )
    {
        m.wyslij();
    }
   
    return m.returnuj();
}


LRESULT CALLBACK WndProc( HWND hwnd, UINT msg, WPARAM wPar, LPARAM lPar )
{
    switch( msg )
    {
    case WM_COMMAND:
        break;
    case WM_PAINT:
        break;
    case WM_CLOSE:
        PostQuitMessage( 0 );
        break;
        default:
        return DefWindowProc( hwnd, msg, wPar, lPar );
    }
    return 0;
}
P-133340
pekfos
» 2015-06-08 19:47:17
Źle używasz zmiennych globalnych. W praktyce w ogóle nie powinieneś ich tu używać. Zacznij od sensownego projektu, bo ten twój wrapper jest naprawdę mierny.
P-133343
jankustosz
Temat założony przez niniejszego użytkownika
» 2015-06-08 20:46:29
źle używam zmiennych globalnych w pliku main.cpp czy chodzi ci o vector <Element *> elementy w pliku WinMain.cpp?
P-133349
Monika90
» 2015-06-08 20:52:43
Chodzi o to, że zmienne globalne w pliku main.cpp są tworzone (inicjalizowane) zanim utworzona zostanie zmienna elementy w pliku winapi.cpp.
Możesz sobie poczytać o tym tu https://isocpp.org/wiki/faq​/ctors#static-init-order, ale najlepiej nie używaj zmiennych globalnych.

P-133350
jankustosz
Temat założony przez niniejszego użytkownika
» 2015-06-08 21:56:19
Te zmienne przecież muszą być globalne żeby móc się do nich odwoływać w funkcji WndProc.
P-133353
pekfos
» 2015-06-08 22:07:02
Poczytaj sobie o czymś takim, jak singleton.
P-133354
« 1 » 2 3 4
  Strona 1 z 4 Następna strona