2017-12-30 31 views
-2

Ich habe eine Klasse Socket, mit zwei Konstruktoren genannt:Objekt als privates Mitglied einer Klasse

Socket(int port){...} 
Socket(string address, int port){...} 

Ich mag eine Instanz dieser Socket-Klasse als privates Mitglied einer anderen Klasse verwenden, die Connection-Klasse, wie folgt aus:

class Connection{ 
    private: 
    Socket socket; 
    //more stuff 
}; 

im Konstruktor der Klasse Connection ich möchte nur als Parameter eine Instanz von Socket passieren und es an den privaten Mitglied zuweisen, wie folgt aus:

Connection:Connection(Socket socket){ 
    this->socket = socket; 
    //... 
} 

Aber der Compiler fordert mich auf, den Konstruktor Socket im Connection-Konstruktor aufzurufen (oder zumindest denke ich das); Ich erhalte diese Fehlermeldung:

error: no matching function for call to ‘Socket::Socket()’ Connection::Connection(Socket socket)

Was ist der richtige Weg, das zu tun ist (die Socket außerhalb erklärt und als Parameter in dem Connection Konstruktor)?

+0

Mögliche Duplikat [Aufruf Konstruktor einer Klasse Mitglied in Konstruktor] verwenden (https://stackoverflow.com/questions/7761676/calling-constructor-of-a-class-member-in-constructor) –

Antwort

2

Was im Connection Konstruktor geschieht, ist, dass das erste Element socketStandard ist aufgebaut, als Teil des Objekts initialisiert werden. Und Sie haben keinen Standardkonstruktor Socket (ein Konstruktor, der keine Argumente annimmt).

Nach fest, dass der Körper des Konstruktors ausgeführt wird, und die Kopie Zuordnung vorgenommen wird (zu einem bereits vorhandenen Objekt).

sollten Sie verwenden einen Konstruktor Initialisiererliste zu konstruieren/initialisieren die Mitglieder:

Connection:Connection(Socket socket) 
    : socket(socket) 
{} 

Auf einem sehr ähnlichen Hinweis: Die socket Objekt innerhalb des Connection Objekt ist ein Kopie der Ist Socket Instanz! Was in der obigen Initialisierungsliste passiert, ist, dass das Objekt socketist, das durch Kopieren konstruiert wurde.

Sie sollten wahrscheinlich Referenzen verwenden, wenn Sie das Original Socket verweisen möchten:

class Connection 
{ 
    ... 
    Socket& socket; 
}; 
+0

Vielen Dank für Ihre klärende Antwort. Weißt du, dass es ein Problem mit der Verwendung einer Kopie des Sockets anstelle des Originals gibt? Meine Socket-Klasse funktioniert mit UNIX-Socket-Systemaufrufen. – pitazzo

+0

@pitazzo Ich weiß nicht, was die 'Socket' Klasse intern tut, kann ich nicht sagen. Es hängt wirklich davon ab, was Sie tun, im Anwendungsfall. –

2

Verwenden Sie stattdessen , z.

Connection:Connection(Socket socket) : socket(socket) {} 

For members that cannot be default-initialized, such as members of reference and const-qualified types, member initializers must be specified.

Für Ihren Ansatz weist das Datenelement socket Standard zunächst initialisiert werden, dann in den Körper des Konstruktor zugewiesen. Aber Socket hat keinen Standardkonstruktor und kann nicht standardmäßig initialisiert werden.

BTW: Der Standardkonstruktor wird implicitly generated für Socket nicht sein, da es von Benutzern bereitgestellte Konstruktoren hat.

2

Sie weisen dem standardmäßig konstruiertensocket Mitglied einen neuen Socket zu. Und da es keinen Standardkonstruktor für die Klasse Socket gibt, gibt der Compiler diesen Fehler.

// Here, 'socket' is assigned to the default constructed 'this->socket'. 
this->socket = socket; 

zu initialisieren/konstruieren die this->socket Sie sie in der Member Initialisiererliste schreiben sollte:

Connection:Connection(Socket socket) : socket(socket) { 
} 

Auf diese Weise this->socket ist Kopie aus dem gegebenen socket konstruiert.

1

Wie oben gesagt, wird das Datenelement Buchse bereits an dem Punkt konstruierten Standardwert ist die Kopie-Zuordnung genannt:

{ 
    // this->socket is already default-constructed here 
    // but no default constructor Socket() available -> ERROR 
    this->socket = socket; 
} 

, die für den Socket-Konstruktor sollte ausdrücklich genannt werden, und das hat in Verbindung Konstruktor initliazer Liste sein (außerhalb des Konstruktorfunktion Körper):

Connection::Connection(Socket sock) : socket(sock) {} 

Wenn Sie eine Steckdose Kopie in Ihrem Connection-Klasse wollen, möchten Sie wahrscheinlich

Connection::Connection(const Socket& sock) 

statt Connection::Connection(Socket sock)

Verwandte Themen