是否有可能成员初始化推迟到构造函数体? [英] Is it possible to defer member initialization to the constructor body?

查看:141
本文介绍了是否有可能成员初始化推迟到构造函数体?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个对象不具有默认构造函数成员的类。我想初始化这个成员在构造函数中,但似乎在C ++中,我不能这样做。这里是类:

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);
}

编译器告诉我,基本上,它找不到UDP套接字::默认构造函数和我的研究,我了解C ++隐式调用构造函数之前,每一个成员初始化。有没有办法做到这一点,我想做到这一点,或者是它太面向Java,并用C不可行++?

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);
}

所以我的问题是更多出于好奇并更好地了解OOP在C ++

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

推荐答案

当你定义一个构造函数,你有2种方式初始化属性:

When you define a constructor, you have 2 ways to "initialize" attributes:


  • 初始化列表

  • 构造函数体

如果你没有显式初始化在初始化列表中的属性之一,但却是初始化(通过调用其默认构造函数)为您...

If you do not explictly initialize one of the attributes in the initializer list, it is nonetheless initialized (by calling its default constructor) for you...

因此​​,在本质:

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

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

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

如果基础类型不具有默认构造函数这门课程的失败。

And this of course fails if the underlying type does not have a Default Constructor.

有各种方式推迟此初始化。 标准的方式是使用一指针:

There are various ways to defer this initialization. The "standard" way would be to use a pointer:

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

不过,我使用preFER 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); }

由于Boost.Optional意味着有该分配没有开销并在间接引用没有开销(对象以代替创建)和尚未进行正确的语义

Because Boost.Optional means that there is no overhead on the allocation and no overhead on the dereferencing (the object is created in place) and yet carries the correct semantic.

这篇关于是否有可能成员初始化推迟到构造函数体?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆