CYFROWY BARON • PROGRAMOWANIE • Zobacz wątek - niszczenie "obiektów" klasy wewnątrz konstruktora
Strona 3 z 4

Re: niszczenie "obiektów" klasy wewnątrz konstruktora

Nowy postNapisane: środa, 11 maja 2011, 12:57
przez Slynx
KOD cpp:     UKRYJ  
virt^ z = gcnew xx;

Taki zapis nie wywołuje konstruktora, tylko
KOD cpp:     UKRYJ  
virt^ z = gcnew xx();

A ten drugi zapis jest niemożliwy (błąd kompilacji)

Chyba, że w klasach wirtualnych to działa jakoś inaczej.

Re: niszczenie "obiektów" klasy wewnątrz konstruktora

Nowy postNapisane: środa, 11 maja 2011, 13:30
przez polymorphism
Jak nie wywołuje konstruktora? W C++ nie ma takiej opcji.

Re: niszczenie "obiektów" klasy wewnątrz konstruktora

Nowy postNapisane: środa, 11 maja 2011, 13:58
przez Slynx
No to teraz to już mi w ogóle namotałeś w głowie.

Przecież wywołanie konstruktora dla klasy musi być zakończone parą nawiasów, gdzie są podawane argumenty lub puste nawiasy gdy argumentów nie ma,
więc taki zapis
KOD cpp:     UKRYJ  
virt^ z = gcnew xx;

nie wywoła konstruktora klasy xx... chyba.

Re: niszczenie "obiektów" klasy wewnątrz konstruktora

Nowy postNapisane: środa, 11 maja 2011, 14:13
przez polymorphism
Jeszcze raz napiszę: nie ma takiej opcji! Konstruktor to nie jest zwykła metoda, którą możesz sobie wywołać lub nie. On jest zawsze wywoływany w momencie, gdy tworzysz nowy obiekt danej klasy. Jego rolą jest inicjalizacja pól klasy, np. zerowanie wskaźników, czy też odpalanie konstruktorów klas bazowych i składowych. Dlatego klasa, której konstruktor nie został wywołany, nie została poprawnie stworzona - innymi słowy nastąpił jakiś błąd.

Re: niszczenie "obiektów" klasy wewnątrz konstruktora

Nowy postNapisane: środa, 11 maja 2011, 14:24
przez Slynx
To czemu w tym wypadku tworzy się w ten sposób
KOD cpp:     UKRYJ  
virt^ z = gcnew xx;

a nie jak zawsze
KOD cpp:     UKRYJ  
virt^ z = gcnew xx();

Re: niszczenie "obiektów" klasy wewnątrz konstruktora

Nowy postNapisane: środa, 11 maja 2011, 14:41
przez polymorphism
Nie wiem, być może taka uroda C++/CLI. W standardowym C++, przy dynamicznym tworzeniu klasy operatorem new, obie formy są poprawne. Jedynie podczas tworzenia na stosie nawiasy będą powodować błędy kompilacji.

Osobiście zawsze stosuję formę pierwszą.

Re: niszczenie "obiektów" klasy wewnątrz konstruktora

Nowy postNapisane: środa, 11 maja 2011, 15:58
przez Slynx
Nom, sprawdziłem i masz rację, wywołuje konstruktor wirtualnej klasy bazowej i klasy obiektu który tworzymy.
Może to miała być jakaś forma informowania, że odwołujemy się przez klasę wirtualną czy coś... zresztą, co to ma za znaczenie, ważne, że działa jak należy.
Teraz tylko deklaracje zapowiadające....
///
Już wiem o co chodzi. Przy kompilowaniu wyskoczył mi błąd. Taka konstrukcja wywołuje konstruktor domyślny, czyli tak jak u mnie są - z argumentami - już nie przejdzie :/
Muszę stworzyć drugą funkcję w stylu init() i przenieść do niej wszystko :/
//
... dla klasy abstrakcyjnej... ehh
//
Ok, wszystko się kompiluje, nawet chyba dobrze działa, choć mam ładny śmietnik. Muszę zobaczyć co z tego wyjdzie, czy to w ogóle miało jakiś sens, bo żeby skompilować musiałem trochę kodu przeprawić...

Re: niszczenie "obiektów" klasy wewnątrz konstruktora

Nowy postNapisane: środa, 11 maja 2011, 18:20
przez Slynx
No dobra, jeszcze te deklaracje, bo nie mogę tego zrobić, więc
klasa abstrakcyjna mailbox
KOD cpp:     UKRYJ  
#include "host_1.h"
#include "host_2.h"

namespace xxx
{
        namespace yyy
        {
                public ref class MailBox abstract
                {
                   //deklaracja host_1
                {  
         }
}
 

host_1
KOD cpp:     UKRYJ  
#include "MailBox.h"
#include "addin.h"
namespace xxx
{
        namespace zzz
        {
                ref class xxx::yyy::MailBox;
                public ref class host_1 : public xxx::yyy::MailBox
                  {
/// Tu tylko redefinicja metody wirtualnej i użycie metod klasy "addin"
                  }
        }
}
 

No i wydawało mi się, że w klasie hosta trzeba dać "ref class MailBox", bo jest używany jako base class, ale nie działało.
Ogólny błąd

host_1.h(11) : error C2039: 'MailBox' : is not a member of xxx::yyy'


zrobiłem odwrotnie i dodałem "ref class xxx::zzz:host_1" i też nic.

Re: niszczenie "obiektów" klasy wewnątrz konstruktora

Nowy postNapisane: środa, 11 maja 2011, 19:55
przez polymorphism
Że tak spytam, po co klasie bazowej (MailBox) wiedza o jej pochodnej (host_1)? Po co w pliku host_1 dajesz deklarację zapowiadającą klasy MailBox, jeśli parę linii wyżej załączyłeś plik z jej definicją?

Dodam do słów kluczy jeszcze dwa: interfejs i/lub klasa czysto abstrakcyjna.

Re: niszczenie "obiektów" klasy wewnątrz konstruktora

Nowy postNapisane: środa, 11 maja 2011, 20:22
przez Slynx
Dobra, bo ja już mam dość słów kluczowych, dalej nie mogę sobie poradzić z tym wcześniejszym bo mój pomysł okazał się niemożliwy do zrealizowania (albo nie wiem że tak można)
Chciałem w tej klasie MailBox dodać metodę wirtualną, coś w stylu get, która na wyjściu zwracała by wybrany (przez konstruktor) host, wtedy zapis byłby bardzo prosty.

Na początku chciałem wykorzystać tą funkcję template, bo można by ustawić typ zwracane wartości na obiekt konkretnego hosta. Ale do działania wymaga argumentu na podstawie, którego ustala typ wyjściowy, więc to odpada, bo wróciłbym do tego co na początku( stos deklaracji lub stos argumentów, do wyboru).
Chciałem też stworzyć przeciążoną wersję funkcji z różnymi zwracanymi wartościami (czyli hostami), ale takich funkcji nie można budować tylko na podstawie zwracanej wartości, więc to też odpada.
Z tego wszystkiego i tak nie za bardzo wiem jak to zrobić, bo żeby zapis mógł wyglądać, np. "m_box->Do()->Create();" funkcja Do() musi mieć w return odpowiedni typ. Nie wiem jak inaczej to zrobić by uzyskać coś takiego.

Co do Twojego pytania. Jest bezpośrednio powiązane z problemem wyżej. W pewnym momencie uznałem, że można porobić deklaracje tych typów, poprzez konstruktor stworzyć odpowiedni obiekt, a funkcja już potem tylko zwracać ten właściwy. No ale właśnie jest problem zwracanej wartości.
Może można to zrobić inaczej, ale aż tak obeznany we wszystkich technikach nie jestem i nic innego nie przychodzi mi do głowy :roll:

A klasa MailBox jest klasa abstrakcyjną, wyrzuciłem z niej wszystko, został tylko domyślny konstruktor, wirtualny destruktor i funkcja czysto wirtualna Do(). Poza tym, jest słowo kluczowe abstract przy nazwie klasy.

Re: niszczenie "obiektów" klasy wewnątrz konstruktora

Nowy postNapisane: środa, 11 maja 2011, 20:27
przez polymorphism
Zupełnie nie zrozumiałeś idei polimorfizmu.

Może powiedz, czym są host_n, jaka jest ich funkcja. Być może pisałeś już to w tym temacie, ale nie pamiętam.

Re: niszczenie "obiektów" klasy wewnątrz konstruktora

Nowy postNapisane: środa, 11 maja 2011, 20:48
przez Slynx
host_n odpowiadają za podstawowe funkcje (kreator, logowanie, download), w pełni obsługują danego hosta (korzystając z możliwości klasy - w kodzie oznaczonej jako addin). Bardzo prawdopodobne, że potem z nich zrobię dllki, ale teraz chcę by to w ogóle działało.
Natomiast klasa MailBox, zbiera je wszystkie, łączy je w "jeden punkt wyjścia" tak, by można było obsłużyć je uniwersalnie (czyli wywołanie o którym cały czas mówiłem).

Re: niszczenie "obiektów" klasy wewnątrz konstruktora

Nowy postNapisane: czwartek, 12 maja 2011, 09:59
przez polymorphism
Czyli, jak rozumiem, hosty posiadają pewną liczbę wspólnych metod, zatem bez problemu możesz ich deklaracje dodać do klasy interfejsu. Im więcej tych metod, tym lepiej, ponieważ wtedy możesz pisać kod pod interfejs, uniezależniając go od konkretnych implementacji hostów. I dlatego pisałem, żebyś zainteresował się polimorfizmem.

Re: niszczenie "obiektów" klasy wewnątrz konstruktora

Nowy postNapisane: czwartek, 12 maja 2011, 10:25
przez Slynx
Metody to one mają wszystkie takie same, czasami może tylko jednej brakować w tym lub w tym, ale nazwy (w 90 %) się pokrywają. Ale dalej nie rozumiem, jak to przełożyć.
Podaj mi jakiś konkretny przykład (w kodzie) ja spróbuję to przełożyć do siebie.

Chyba częściowo rozumiem... nie chodzi o to, żeby ta klasa wirtualna posiadała jedną funkcje zwracającą, ale deklarację metod wykorzystywanych przez skrzynki. Wtedy skrzynki będą korzystać z tych metod, a typ zwracanej wartości nie będzie miał żadnego znaczenia. Ale na razie to tylko taka nowa wstępna teoria ; p

Re: niszczenie "obiektów" klasy wewnątrz konstruktora

Nowy postNapisane: czwartek, 12 maja 2011, 11:27
przez polymorphism
KOD cpp:     UKRYJ  
class MailBox //<--- interfejs
{
public:
        virtual string getName() = 0;
        virtual void Connect() = 0;
        virtual void Disconnect() = 0;
        virtual ~MailBox() {};
};

class Host1: public MailBox
{
public:
        string getName() { return "Host 1"; }
        void Connect() {}
        void Disconnect() {}
};

class Host2: public MailBox
{
public:
        string getName() { return "Host 2"; }
        void Connect() {}
        void Disconnect() {}
};

...
 


KOD cpp:     UKRYJ  
vector<MailBox*> m_mailboxes;


...

m_mailboxes.push_back(new Host1);
m_mailboxes.push_back(new Host2);
m_mailboxes.push_back(new Host3);
m_mailboxes.push_back(new Host4);

...

for(int i = 0; i < m_mailboxes.size(); ++i)
{
        cout << "connecting " << m_mailboxes[i]->getName() << '\n';
        m_mailboxes[i]->Connect();
}
 

Zwróć uwagę, że kod pętli jest niezależny od tego, jakiego typu jest host, który łączy. Dzieje się tak, ponieważ korzysta ze wspólnego dla wszystkich typów hostów interfejsu.