I've a class called Socket
, with two constructors:
我有一个名为Socket的类,有两个构造函数:
Socket(int port){...}
Socket(string address, int port){...}
I'd like to use one instance of that Socket class as a private member of another class, the Connection class, like this:
我想使用该Socket类的一个实例作为另一个类的私有成员,Connection类,如下所示:
class Connection{
private:
Socket socket;
//more stuff
};
In the constructor of the Connection
class I just want to pass as parameter one instance of Socket
and assign it to the private member, like this:
在Connection类的构造函数中,我只想作为参数传递一个Socket实例并将其分配给私有成员,如下所示:
Connection:Connection(Socket socket){
this->socket = socket;
//...
}
But the compiler asks me to call the Socket
constructor inside the Connection constructor (or at least I think that); I'm getting this error:
但是编译器要求我在Connection构造函数中调用Socket构造函数(或者至少我认为);我收到这个错误:
error: no matching function for call to ‘Socket::Socket()’ Connection::Connection(Socket socket)
错误:没有匹配函数来调用'Socket :: Socket()'Connection :: Connection(套接字套接字)
Which is the right way to do that (declaring the Socket
outside and passing it as parameter in the Connection
constructor)?
哪种方法是正确的(将Socket声明为外部并将其作为Connection构造函数中的参数传递)?
4 个解决方案
#1
2
What happens in the Connection
constructor is that the socket
member is first default constructed, as part of the object initialization. And you don't have a Socket
default constructor (a constructor which takes no arguments).
在Connection构造函数中发生的事情是,作为对象初始化的一部分,套接字成员首先是默认构造的。而且你没有Socket默认构造函数(一个不带参数的构造函数)。
After that, the body of the constructor is executed, and the copy assignment is made (to an already existing object).
之后,执行构造函数的主体,并进行复制分配(到现有对象)。
You should use a constructor initializer list to construct/initialize the members:
您应该使用构造函数初始化列表来构造/初始化成员:
Connection:Connection(Socket socket)
: socket(socket)
{}
On a very related note: The socket
object inside the Connection
object is a copy of the actual Socket
instance! What happens in the above initializer list is that the socket
object is copy-constructed.
在一个非常相关的说明:Connection对象内的套接字对象是实际Socket实例的副本!上面的初始化列表中发生的是socket对象是复制构造的。
You should probably use references if you want to reference the original Socket
:
如果要引用原始Socket,则应该使用引用:
class Connection
{
...
Socket& socket;
};
#2
2
You're actually assigning a new Socket
to the default constructed socket
member. And since there's no default constructor for Socket
class, compiler gives you that error.
您实际上是将新Socket分配给默认构造的套接字成员。由于Socket类没有默认构造函数,编译器会给出错误。
// Here, 'socket' is assigned to the default constructed 'this->socket'.
this->socket = socket;
To initialize/construct the this->socket
, you should write it in the member initializer list:
要初始化/构造this-> socket,您应该在成员初始化列表中编写它:
Connection:Connection(Socket socket) : socket(socket) {
}
This way, this->socket
is copy constructed from the given socket
.
这样,this-> socket是从给定套接字构造的。
#3
2
Use member initializer list instead, e.g.
改为使用成员初始化列表,例如
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.
对于无法进行默认初始化的成员(例如引用成员和const限定类型),必须指定成员初始值设定项。
For your approach, the data member socket
has to be default initialized at first, then assigned in the constructor's body. But Socket
doesn't have default constructor and can't be default initialized.
对于您的方法,数据成员套接字必须首先默认初始化,然后在构造函数体中分配。但是Socket没有默认构造函数,不能默认初始化。
BTW: The default constructor won't be implicitly generated for Socket
because it has user-provided constructors.
BTW:不会为Socket隐式生成默认构造函数,因为它具有用户提供的构造函数。
#4
1
Like said above, the data member socket is already default-constructed at the point the copy-assignment is called:
如上所述,数据成员套接字在调用复制赋值时已经默认构造:
{
// this->socket is already default-constructed here
// but no default constructor Socket() available -> ERROR
this->socket = socket;
}
That for the Socket constructor should be explicitely called, and that has to be within Connection constructor initliazer list (outside the constructor function body):
应该明确地调用Socket构造函数,并且必须在Connection构造函数initliazer列表中(在构造函数体外):
Connection::Connection(Socket sock) : socket(sock) {}
If you want a socket copy within your Connection class, you probably want to use
如果您想在Connection类中使用套接字副本,则可能需要使用
Connection::Connection(const Socket& sock)
instead of Connection::Connection(Socket sock)
而不是Connection :: Connection(插座袜子)
#1
2
What happens in the Connection
constructor is that the socket
member is first default constructed, as part of the object initialization. And you don't have a Socket
default constructor (a constructor which takes no arguments).
在Connection构造函数中发生的事情是,作为对象初始化的一部分,套接字成员首先是默认构造的。而且你没有Socket默认构造函数(一个不带参数的构造函数)。
After that, the body of the constructor is executed, and the copy assignment is made (to an already existing object).
之后,执行构造函数的主体,并进行复制分配(到现有对象)。
You should use a constructor initializer list to construct/initialize the members:
您应该使用构造函数初始化列表来构造/初始化成员:
Connection:Connection(Socket socket)
: socket(socket)
{}
On a very related note: The socket
object inside the Connection
object is a copy of the actual Socket
instance! What happens in the above initializer list is that the socket
object is copy-constructed.
在一个非常相关的说明:Connection对象内的套接字对象是实际Socket实例的副本!上面的初始化列表中发生的是socket对象是复制构造的。
You should probably use references if you want to reference the original Socket
:
如果要引用原始Socket,则应该使用引用:
class Connection
{
...
Socket& socket;
};
#2
2
You're actually assigning a new Socket
to the default constructed socket
member. And since there's no default constructor for Socket
class, compiler gives you that error.
您实际上是将新Socket分配给默认构造的套接字成员。由于Socket类没有默认构造函数,编译器会给出错误。
// Here, 'socket' is assigned to the default constructed 'this->socket'.
this->socket = socket;
To initialize/construct the this->socket
, you should write it in the member initializer list:
要初始化/构造this-> socket,您应该在成员初始化列表中编写它:
Connection:Connection(Socket socket) : socket(socket) {
}
This way, this->socket
is copy constructed from the given socket
.
这样,this-> socket是从给定套接字构造的。
#3
2
Use member initializer list instead, e.g.
改为使用成员初始化列表,例如
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.
对于无法进行默认初始化的成员(例如引用成员和const限定类型),必须指定成员初始值设定项。
For your approach, the data member socket
has to be default initialized at first, then assigned in the constructor's body. But Socket
doesn't have default constructor and can't be default initialized.
对于您的方法,数据成员套接字必须首先默认初始化,然后在构造函数体中分配。但是Socket没有默认构造函数,不能默认初始化。
BTW: The default constructor won't be implicitly generated for Socket
because it has user-provided constructors.
BTW:不会为Socket隐式生成默认构造函数,因为它具有用户提供的构造函数。
#4
1
Like said above, the data member socket is already default-constructed at the point the copy-assignment is called:
如上所述,数据成员套接字在调用复制赋值时已经默认构造:
{
// this->socket is already default-constructed here
// but no default constructor Socket() available -> ERROR
this->socket = socket;
}
That for the Socket constructor should be explicitely called, and that has to be within Connection constructor initliazer list (outside the constructor function body):
应该明确地调用Socket构造函数,并且必须在Connection构造函数initliazer列表中(在构造函数体外):
Connection::Connection(Socket sock) : socket(sock) {}
If you want a socket copy within your Connection class, you probably want to use
如果您想在Connection类中使用套接字副本,则可能需要使用
Connection::Connection(const Socket& sock)
instead of Connection::Connection(Socket sock)
而不是Connection :: Connection(插座袜子)