Kji*_*jir 4 c++ oop constructor boost initialization
我有一个类,对象作为成员,没有默认的构造函数.我想在构造函数中初始化这个成员,但似乎在C++中我不能这样做.这是班级:
#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);
}
Run Code Online (Sandbox Code Playgroud)
编译器基本上告诉我它找不到udp :: socket的默认构造函数,根据我的研究,我理解C++在调用构造函数之前隐式初始化每个成员.有没有办法以我想要的方式去做,或者它是否"面向Java"并且在C++中不可行?
我通过像这样定义我的构造函数解决了这个问题:
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);
}
Run Code Online (Sandbox Code Playgroud)
所以我的问题更多的是出于好奇并且更好地理解C++中的OOP
定义构造函数时,有两种方法可以"初始化"属性:
如果你没有明确地初始化初始化列表中的一个属性,那么它仍然会被初始化(通过调用它的默认构造函数)...
所以本质上:
class Example
{
public:
Example();
private:
Bar mAttr;
};
// You write
Example::Example() {}
// The compiler understands
Example::Example(): mAttr() {}
Run Code Online (Sandbox Code Playgroud)
如果底层类型没有默认构造函数,这当然会失败.
有多种方法可以推迟初始化."标准"方式是使用指针:
class Example { public: Example(); private: Bar* mAttr; };
Run Code Online (Sandbox Code Playgroud)
但是我更喜欢使用Boost.Optional和合适的访问器:
class Example
{
public: Example();
private:
Bar& accessAttr() { return *mAttr; }
const Bar& getAttr() const { return *mAttr; }
boost::Optional<Bar> mAttr;
};
Example::Example() { mAttr = Bar(42); }
Run Code Online (Sandbox Code Playgroud)
因为Boost.Optional意味着分配没有开销,并且解除引用没有开销(对象是在适当的位置创建的),但却带有正确的语义.