VC++ 2010 Express Deklaracja obiektu

0

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?

0

Zdefiniować go w main() a później przekazywać jako parametr funkcji(referencje bądź wskaźnik).

0
  1. Czy przy programie w Windows Forms to również się sprawdzi?

  2. 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?

0

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.

0
  1. 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 #regionem).
    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:

  • unikać całkowicie potrzeby "niekoszernej" konstrukcji, a jeśli to absolutnie niemożliwe, to
  • świadomie złamać zasadę.

W twoim przypadku być może wystarczyłoby pole w klasie formy.

0

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.

0
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.

0

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.

0

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?

0

Rzeczywiście, nie da się w klasie zarządzanej zadeklarować:

std::vector<int> wu;

(ani publicznie ani prywatnie).

Masz dwa trzy wyjścia:

  • wskaźnik
std::vector<int> *wu;

z odpowiednim new w konstruktorze i delete w destruktorze, albo

  • użycie odpowiednika z .NET Framework
System::Collections::Generic::List<int> wu;
  • użycie 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.

0

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);
}

}

1 użytkowników online, w tym zalogowanych: 0, gości: 1