Witam,
Mam w programie obiekt klasy vector zadeklarowany globalnie na początku programu. Gdzie wrzucić deklarację, aby uniknąć stosowania zmiennych globalnych, a jednocześnie mieć dostęp do zawartości tego obiektu z wielu miejsc w programie?
Witam,
Mam w programie obiekt klasy vector zadeklarowany globalnie na początku programu. Gdzie wrzucić deklarację, aby uniknąć stosowania zmiennych globalnych, a jednocześnie mieć dostęp do zawartości tego obiektu z wielu miejsc w programie?
Zdefiniować go w main() a później przekazywać jako parametr funkcji(referencje bądź wskaźnik).
Czy przy programie w Windows Forms to również się sprawdzi?
Kiedy wybieram jakimś event dla kontrolki (np. kliknięcie dla Button'a) VS tworzy mi obsługę tego zdarzenia w pliku Form1.h i tam mogę wpisać kod obsługi zdarzenia. Czy tak jest poprawnie?
Ad1. To się sprawdzi prawie w każdym języku, nie tylko w C/C++
Ad2. Poprawnie to się robi w Form1.cpp ale w Form1.h musi być deklaracja.
- Kiedy wybieram jakimś event dla kontrolki (np. kliknięcie dla Button'a) VS tworzy mi obsługę tego zdarzenia w pliku Form1.h i tam mogę wpisać kod obsługi zdarzenia. Czy tak jest poprawnie?
Możesz rozdzielić na.h
i.cpp
, zostawiając w .h tylko deklarację funkcji, a w .cpp definicję, ale będzie to ciągła walka z designerem, który każdą nową funkcję będzie wrzucał ci w całości do pliku nagłówkowego.
Możesz tak przenieść też konstruktor formy, i warunkowo funkcjęInitializeComponent
(musi być wraz z okalającym#region
em).
To ostatnie (InitializeComponent) na pewno daje się przenieść w VS2012, i na pewno nie daje w VS2008. Nie wiem jak w 2010.
uniknąć stosowania zmiennych globalnych, a jednocześnie mieć dostęp do zawartości tego obiektu z wielu miejsc w programie?
To jest jakiś problem projektowy. Chcesz uniknąć zmiennej globalnej (bo jest niekoszerna), ale jednocześnie chcesz mieć zmienną zachowującą się jak globalna.
Nie o to chodzi, by omijać zasady dobrego programowania. Chodzi w tego typu zasadach o to, by:
W twoim przypadku być może wystarczyłoby pole w klasie formy.
Możesz rozdzielić na
.h
i.cpp
, zostawiając w .h tylko deklarację funkcji, a w .cpp definicję, ale będzie to ciągła walka z designerem, który każdą nową funkcję będzie wrzucał ci w całości do pliku nagłówkowego.
Hmm... czyli generalnie w VS nie jest źle widziana sytuacja kiedy definicja funkcji jest w pliku nagłówkowym?
W twoim przypadku być może wystarczyłoby pole w klasie formy.
W tym momencie nie mam możliwości sprawdzenia, ale coś mi się kojarzy, że umieszczenie definicji vector <int> w części public klasy Form1 generowało błąd. Można było wstawiać .NET'owy wektor, ale nie ten z biblioteki standardowej.
neutrino napisał(a):
Hmm... czyli generalnie w VS nie jest źle widziana sytuacja kiedy definicja funkcji jest w pliku nagłówkowym?
Nie! W całym C++nie jest źle widziana taka sytuacja.
Owszem WC to nie do końca C++ ale podstawy są takie same.
neutrino napisał(a):
W tym momencie nie mam możliwości sprawdzenia, ale coś mi się kojarzy, że umieszczenie definicji vector <int> w części public klasy Form1 generowało błąd.
O ile nie dodałeś odpowiednich nagłówków to owszem.
OK. Niemniej zawsze znałem podział:
.h - deklaracje
.cpp - definicje
Jeśli chodzi o dodanie plików nagłówkowych typu #include <vector> to były oczywiście dodane.
O ile mnie pamięć nie myli to miałem błąd: mixed types are not supported.
Generalnie mogłem do klasy dorzucić definicje zmiennych typu managed jedynie.
W konsekwencji wszelkie moje wektorki były umieszczone zaraz na początku pliku Form1.h, a nie w polach klasy tak jak sugerował przedmówca.
Po pierwsze jedynie kto może ci zabronić w swoim projekcie używać:
.ale - deklaracje
.fajne - definicje
to tylko twój zdrowy rozsądek.
Po drugie:
class Foo
{
public:
Foo()
{
// tu ciało konstruktora, ten konstruktor mimo wszystko jest definicją.
}
};
inline void foo(void)
{
//tu treść, ta funkcja mimo wszystko jest definicją (inline)
}
"mixed types are not supported" - jakiego słowa nie rozumiesz?
Rzeczywiście, nie da się w klasie zarządzanej zadeklarować:
std::vector<int> wu;
(ani publicznie ani prywatnie).
Masz dwa trzy wyjścia:
std::vector<int> *wu;
z odpowiednim new
w konstruktorze i delete
w destruktorze, albo
System::Collections::Generic::List<int> wu;
cliext::vector
zamiast std::vector
:#include <cliext/vector>
...
cliext::vector<int> wu;
PS. Microsoft obiecał dawno temu obsługę "mixed types", ale biorąc pod uwagę że ich dzisiejszą ulubioną zabawką jest C++/CX, a C++/CLI trafił do pudła wyniesionego do piwnicy, można to podsumować: obiecanki cacanki.
Przykład pustej formy podzielonej na pliki .h
i .cpp
. Działa pod VS2012.
Kod dodatkowo upiększony (wywalone puste linie, komentarze) żeby nie był tak rozwlekły.
Form1.h
#pragma once
namespace delme747474 {
using namespace System;
using namespace System::ComponentModel;
using namespace System::Windows::Forms;
public ref class Form1 : public Form
{
public:
Form1(void);
protected:
~Form1();
private:
IContainer^ components;
void InitializeComponent(void);
};
}
Form1.cpp
#include "stdafx.h"
#include "Form1.h"
namespace delme747474 {
Form1::Form1()
{
InitializeComponent();
}
Form1::~Form1()
{
if (components)
delete components;
}
void Form1::InitializeComponent(void)
{
this->SuspendLayout();
this->AutoScaleDimensions = System::Drawing::SizeF(8, 16);
this->AutoScaleMode = System::Windows::Forms::AutoScaleMode::Font;
this->ClientSize = System::Drawing::Size(282, 199);
this->Name = L"Form1";
this->Text = L"Form1";
this->ResumeLayout(false);
}
}