是否可以将成员初始化推迟到构造函数主体?

2023-12-11

我有一个类,其中一个对象作为成员,但没有默认构造函数。我想在构造函数中初始化这个成员,但似乎在 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);
}

编译器基本上告诉我它找不到 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);
}

所以我的问题更多是出于好奇,为了更好地理解 C++ 中的 OOP


定义构造函数时,有两种方法来“初始化”属性:

  • 初始化列表
  • 构造函数体

如果您没有显式初始化初始化列表中的某个属性,它仍然会为您初始化(通过调用其默认构造函数)...

所以本质上:

class Example
{
public:
  Example();
private:
  Bar mAttr;
};

// You write
Example::Example() {}

// The compiler understands
Example::Example(): mAttr() {}

如果基础类型没有默认构造函数,这当然会失败。

有多种方法可以推迟此初始化。 “标准”方法是使用指针:

class Example { public: Example(); private: Bar* mAttr; };

不过我更喜欢使用升压可选与合适的访问器结合使用:

class Example
{
public: Example();
private:
  Bar& accessAttr() { return *mAttr; }
  const Bar& getAttr() const { return *mAttr; }
  boost::Optional<Bar> mAttr;
};

Example::Example() { mAttr = Bar(42); }

因为 Boost.Optional 意味着分配上没有开销,解引用上也没有开销(对象是就地创建的),并且具有正确的语义。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

是否可以将成员初始化推迟到构造函数主体? 的相关文章

随机推荐