Is it possible to defer member initialization to t

2020-03-25 03:44发布

I have a class with an object as a member which doesn't have a default constructor. I'd like to initialize this member in the constructor, but it seems that in C++ I can't do that. Here is the class:

#include <boost/asio.hpp>
#include <boost/array.hpp>

using boost::asio::ip::udp;

template<class T>
class udp_sock
{
    public:
        udp_sock(std::string host, unsigned short port);
    private:
        boost::asio::io_service _io_service;
        udp::socket _sock;
        boost::array<T,256> _buf;
};

template<class T>
udp_sock<T>::udp_sock(std::string host = "localhost",
  unsigned short port = 50000)
{
    udp::resolver res(_io_service);
    udp::resolver::query query(udp::v4(), host, "spec");
    udp::endpoint ep = *res.resolve(query);
    ep.port(port);
    _sock(_io_service, ep);
}

The compiler tells me basically that it can't find a default constructor for udp::socket and by my research I understood that C++ implicitly initializes every member before calling the constructor. Is there any way to do it the way I wanted to do it, or is it too "Java-oriented" and not feasible in C++?

I worked around the problem by defining my constructor like this:

template<class T>
udp_sock<T>::udp_sock(std::string host = "localhost",
  unsigned short port = 50000) : _sock(_io_service)
{
    udp::resolver res(_io_service);
    udp::resolver::query query(udp::v4(), host, "spec");
    udp::endpoint ep = *res.resolve(query);
    ep.port(port);
    _sock.bind(ep);
}

So my question is more out of curiosity and to better understand OOP in C++

7条回答
趁早两清
2楼-- · 2020-03-25 04:24

If it's to initialize a variable during construction in a class's constructor the right way is:

template<class T>
udp_sock<T>::udp_sock(std::string host = "localhost", unsigned short port = 50000)
    :res(_io_service)
    ,query(udp::v4(), host, "spec")
    ,ep(*res.resolve(query))
    ,_sock(_io_service, ep)
{
}

Edit: Forgot to mention that 'res', 'query' and 'ep' should be part of the class. Another crude method (without having _sock as a pointer) is as given below:

template<class T>
udp_sock<T>::udp_sock(std::string host = "localhost", unsigned short port = 50000)
    :_sock(_io_service, udp::resolver(_io_service).resolve(udp::resolver::query(udp::v4(),host,"spec"))
{
}
查看更多
登录 后发表回答