对象作为类的私有成员

时间:2017-12-30 12:25:42

标签: c++ object

我有一个名为Socket的类,有两个构造函数:

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

我想将该Socket类的一个实例用作另一个类的私有成员Connection类,如下所示:

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

Connection类的构造函数中,我只想作为参数传递Socket的一个实例,并将其分配给私有成员,如下所示:

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

但是编译器要求我在Connection构造函数中调用Socket构造函数(或者至少我认为);我收到了这个错误:

  

错误:没有匹配函数来调用'Socket :: Socket()'   Connection :: Connection(套接字套接字)

这是正确的方法(在Socket构造函数中声明Connection外部并将其作为参数传递)?

4 个答案:

答案 0 :(得分:2)

请改用member initializer list,例如

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

对于无法进行默认初始化的成员,例如引用成员和const限定类型,必须指定成员初始值设定项。

对于您的方法,数据成员socket必须首先默认初始化,然后在构造函数体中分配。但是Socket没有默认构造函数,不能默认初始化。

BTW:Socket的默认构造函数不是implicitly generated,因为它有用户提供的构造函数。

答案 1 :(得分:2)

您实际上是在默认构建的 Socket成员中分配了新的socket。由于Socket类没有默认构造函数,编译器会给出错误。

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

要初始化/构造this->socket,您应该将其写在成员初始化列表中:

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

这样,this->socket是来自给定socket复制构建

答案 2 :(得分:2)

Connection构造函数中发生的事情是socket成员是第一个默认构造的,作为对象初始化的一部分。而且你没有Socket默认构造函数(一个不带参数的构造函数)。

之后,执行构造函数的主体,并进行 copy 赋值(对于已经存在的对象)。

您应该使用构造函数初始化列表来构建/初始化成员:

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

在一个非常相关的说明中:socket对象中的Connection对象是实际Socket实例的副本!上面的初始化列表中发生的情况是socket对象是复制构造的

如果要引用原始Socket,则应该使用引用

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

答案 3 :(得分:1)

如上所述,数据成员套接字在调用复制赋值时已经默认构造:

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

应该明确地调用Socket构造函数,并且必须在Connection构造函数initliazer列表中(在构造函数体外):

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

如果您想在Connection类中使用套接字副本,则可能需要使用

Connection::Connection(const Socket& sock) 

而不是Connection::Connection(Socket sock)