Προς το περιεχόμενο

Προτεινόμενες αναρτήσεις

Δημοσ.

Μπορεί καποιος να μου εξηγησει τον παρακάτω c++ κώδικα;

Στον constructor εχω το βασικό προβλημα...

 

>
class aproxy {
   aproxy( int & r ) : mPtr( & r ) {}
   void operator = ( int n ) {
       if ( n > 1 ) {
               throw "not binary digit";
       }
       *mPtr = n;
   }
   int * mPtr;
};

Δημοσ.

Αρχικοποιεί το μέλος mPtr της κλάσης με το r.

 

Για να μην μακρυγορούμε,

ψάξε να δεις τι είναι το "constructor initialization list" και γιατί γράφεται έτσι...

 

-

Δημοσ.

Καλό θα ήταν να μας πεις και για τι πράγμα ακριβώς ζητάς εξήγηση.

 

Αυτό που μπορώ σίγουρα να σου πω είναι ότι ο συγκεκριμένος κώδικας κάνει πράγματα που δεν πρέπει να βλέπουν το φως της μέρας και αν χρησιμοποιηθεί ως έχει αργά η γρήγορα θα κάνει την παρουσία του αισθητή με την κακή έννοια. Μιλάμε για παράδειγμα προς αποφυγή με όλη τη σημασία της έκφρασης.

Δημοσ.

Καλό θα ήταν να μας πεις και για τι πράγμα ακριβώς ζητάς εξήγηση.

 

Αυτό που μπορώ σίγουρα να σου πω είναι ότι ο συγκεκριμένος κώδικας κάνει πράγματα που δεν πρέπει να βλέπουν το φως της μέρας και αν χρησιμοποιηθεί ως έχει αργά η γρήγορα θα κάνει την παρουσία του αισθητή με την κακή έννοια. Μιλάμε για παράδειγμα προς αποφυγή με όλη τη σημασία της έκφρασης.

 

Αυτος ειναι ο λόγος -> "constructor initialization list"

 

Γιατι ομως κατηγορεις ετσι τον κώδικα;Καλο θα ηταν να εξηγησεις.

Δημοσ.

Γιατι ομως κατηγορεις ετσι τον κώδικα;Καλο θα ηταν να εξηγησεις.

 

>
   aproxy( int & r ) : mPtr( & r ) {}

 

Ο ctor παίρνει reference σε int και μετά αποθηκεύει τη διεύθυνση του. Όταν λοιπόν τη χρησιμοποποιήσει, δεν υπάρχει καμία εγγύηση ότι η μνήμη στην οποία δείχνει πλέον ο mPtr θα μπορεί να προσπελαστεί, πόσο μάλλον ότι θα υπάρχει ακόμα εκεί ο int που πέρασες αρχικά στον ctor. Αυτό σημαίνει ότι υπάρχουν πλούσιες δυνατότητες για σωστή λειτουργία, για λανθασμένα αποτελέσματα και ακόμα και για segfaults.

 

Καταλαβαίνω βέβαια ότι ο σκοπός είναι αργότερα να αλλάξεις την τιμή "του int που πέρασες μέσα", αλλά σ' αυτή την περίπτωση θα έπρεπε ο ctor να παίρνει κατευθείαν int* παράμετρο. Η διαφορά είναι πως βλέποντας int* στο call site γίνεται αμέσως φανερό πως καλά θα κάνεις να φροντίσεις η μνήμη στην οποία δείχνει ο pointer να παραμείνει προσβάσιμη για όλη τη διάρκεια ζωής του aproxy instance, ενώ βλέποντας int& δεν μπορείς να υποθέσεις κάτι ανάλογο.

 

>
   void operator = ( int n ) {
       if ( n > 1 ) {
               throw "not binary digit";
       }
       *mPtr = n;
   }

 

Εδώ τώρα το τι κάνει και το τι λέει ο κώδικας είναι τελείως διαφορετικά. Αυτό που λέει είναι ότι "επιτρέπονται μόνο 0 και 1". Αυτό που κάνει όμως είναι να επιτρέπει επίσης και όλους τους αρνητικούς ακέραιους.

 

Τέλος, το να κάνεις throw οτιδήποτε δεν είναι derived από std::exception (μη πω από std::runtime_error τις περισσότερες φορές) απλά είναι κόντρα στην ιδεολογία της standard library. Δε νομίζω ότι υπάρχει λόγος να πάει κανείς κόντρα, και υπάρχουν διάφοροι λόγοι να μην παει.

  • 2 εβδομάδες αργότερα...
Δημοσ.

Τουτος ο constructor μπορεις να μου εξηγησεις για ποιο λόγο αρχικοποιεί το αντικείμενο imp_ ;;;;

Δουλεύω λίγο το Bridge pattern....

>
class Packet {

public:

	Packet(ProtocolImpl *imp) : imp_(imp) {}

	virtual void send(){
		imp_->send(packetData_);
	}

protected:

	ProtocolImpl *imp_;
	std::string packetData_;
};

 

Ορίστε ολόκληρος ο κώδικας..

 

 

>//---------------------------------------------------------------------------

#include <vcl.h>
#include <iostream.h>

#pragma hdrstop

#include <tchar.h>
//---------------------------------------------------------------------------

class ProtocolImpl{

public:

	virtual void send( const std::string& packetData ) = 0;
};

class UDPProtocolImpl: public ProtocolImpl{

public:

	virtual void send( const std::string& packetData ){
		std::cout << "sending: " << packetData.c_str() << " via UDP" << std::endl;
	}
};

class TCPProtocolImpl: public ProtocolImpl{

public:

	virtual void send( const std::string& packetData ){
		std::cout << "sending: " << packetData.c_str() << " via TCP" << std::endl;
	}
};






class Packet {

public:
								/* αρχικοποιεί το μέλος imp_ σε imp το γιατι δεν το ξέρω... */
	Packet(ProtocolImpl *imp) : imp_(imp) {}

	virtual void send(){
		imp_->send(packetData_);
	}

protected:

	ProtocolImpl *imp_;
	std::string packetData_;
};

class UDPPacket : public Packet {

public:

	UDPPacket(const std::string& packetData)  : Packet(new UDPProtocolImpl()) {
		packetData_ = packetData;
	}
};

class TCPPacket: public Packet {

public:

	TCPPacket(const std::string& packetData) : Packet(new TCPProtocolImpl()) {
		packetData_ = packetData;
	}
};




#pragma argsused
int _tmain(int argc, _TCHAR* argv[])
{
Packet *packets[3];
packets[0] = new UDPPacket("packet data #1");
   packets[1] = new UDPPacket("packet data #2");
   packets[2] = new TCPPacket("packet data #3");
   for (int i = 0; i < 3; i++)
	packets[i]->send();




getchar();
return 0;
}
//---------------------------------------------------------------------------

 

 

Δημοσ.

Τουτος ο constructor μπορεις να μου εξηγησεις για ποιο λόγο αρχικοποιεί το αντικείμενο imp_ ;;;;

Δουλεύω λίγο το Bridge pattern....

 

Δεν είμαι σίγουρος με ποιά έννοια ρωτάς. Ο constructor (πιο σωστά, το constructor initialization list) αποθηκεύει στο imp_ την τιμή που του περνάς σαν πρώτη παράμετρο, κι αυτό γιατί η τιμή αυτή χρειάζεται αργότερα (όταν καλέσεις τη send).

Δημιουργήστε ένα λογαριασμό ή συνδεθείτε για να σχολιάσετε

Πρέπει να είστε μέλος για να αφήσετε σχόλιο

Δημιουργία λογαριασμού

Εγγραφείτε με νέο λογαριασμό στην κοινότητα μας. Είναι πανεύκολο!

Δημιουργία νέου λογαριασμού

Σύνδεση

Έχετε ήδη λογαριασμό; Συνδεθείτε εδώ.

Συνδεθείτε τώρα
  • Δημιουργία νέου...