简体   繁体   English

C ++ 11委派构造函数功能的实现会导致多个警告

[英]Implementation of C++11 delegating constructors feature results in several warnings

I have tried to implement the C++11 feature (I've used this answer as a reference Can I call a constructor from another constructor (do constructor chaining) in C++? ). 我尝试实现C ++ 11功能(我已将此答案用作参考。我可以从C ++中的另一个构造函数调用构造函数(构造函数链接)吗? )。 Obviously, I've done it wrong but I don't understand why. 显然,我做错了,但我不明白为什么。

I get several warnings in the following piece of code: 在以下代码段中,我会收到一些警告:

  • Member _output was not initialized in this constructor 成员_output未在此构造函数中初始化
  • Member _protocol_scanner was not initialized in this constructor 成员_protocol_scanner未在此构造函数中初始化
  • Member _state was not initialized in this constructor 成员_state未在此构造函数中初始化
  • Member _source was not initialized in this constructor 成员_source未在此构造函数中初始化

This is the code: 这是代码:

class UartScanner {
public:
    UartScanner(periph::IStreamDevice *source, periph::IStreamDevice *output);
    UartScanner(periph::IStreamDevice *source);
    ~UartScanner();

private:
typedef enum
{
    WAITING_SYNC,
    WAITING_UBLOX_MSG,
    WAITING_NOVATEL_MSG
} states_t;

    periph::IStreamDevice *_source;
    periph::IStreamDevice *_output;
    ProtocolScanner *_protocol_scanner;
    states_t _state;
};

UartScanner::UartScanner(periph::IStreamDevice *source, IStreamDevice *output):
    _source(source),
    _output(output),
    _state(WAITING_SYNC)
{
    _protocol_scanner = new ProtocolScanner(source,output);
}

UartScanner::UartScanner(periph::IStreamDevice *source): UartScanner(source,0) 
{
}

class IStreamDevice {
public:
    virtual ~IStreamDevice() {}
    virtual uint32_t read(uint8_t* data, uint32_t size) = 0;
    virtual uint32_t write(const uint8_t* data, uint32_t size) = 0;
};

I take a look at your code and I changed a couple of things. 我看一下您的代码,我做了几件事。 I have created a file named Test1.hpp and put your code in it. 我创建了一个名为Test1.hpp的文件,并将您的代码放入其中。 The following code compiled correctly with GCC 4.7 and Clang 3.3 with the -Wall -Werror -pedantic-errors attributes. 以下代码使用带有-Wall -Werror -pedantic-errors属性的GCC 4.7和Clang 3.3正确编译。 Let's see what's the contain of the HPP file. 让我们看看HPP文件包含什么。

#ifndef TEST1_HPP
#define TEST1_HPP
// Some inclusions here ...
namespace periph
{
   class IStreamDevice{ // Something here... };
}

class ProtocolScanner {
    public:
       ProtocolScanner(periph::IStreamDevice *source, periph::IStreamDevice *output) 
          : _source(source), _output(output) { }

    private:
       periph::IStreamDevice *_source;
       periph::IStreamDevice *_output;
};


class UartScanner {
    public:
        UartScanner(periph::IStreamDevice *source, periph::IStreamDevice *output)
          : _source(source), _output(output), _protocol_scanner(new ProtocolScanner(source,output)), _state(states_t::WAITING_SYNC) { }

        UartScanner(periph::IStreamDevice *source) 
          : UartScanner(source, nullptr) { }

        ~UartScanner() { } // I suppose that something is done in the destructor.

    private:
        enum class states_t : uint8_t {
            WAITING_SYNC,
            WAITING_UBLOX_MSG,
            WAITING_NOVATEL_MSG
        };

        periph::IStreamDevice *_source;
        periph::IStreamDevice *_output;
        ProtocolScanner *_protocol_scanner;
        states_t _state;
};

class IStreamDevice {
    public:
        virtual ~IStreamDevice() {}
        virtual uint32_t read(uint8_t* data, uint32_t size) = 0;
        virtual uint32_t write(const uint8_t* data, uint32_t size) = 0;
};

#endif

Notice that I added a namespace and some other classes you used. 注意,我添加了名称空间和您使用的其他一些类。 Since I don't know their definition, I let them empty to make that working. 由于我不知道它们的定义,因此我让他们空白以使它起作用。 Now, let's review this code. 现在,让我们回顾一下此代码。

In C++11, if you want to initialize a pointer to NULL, I suggest you to use the nullptr keyword to do the job. 在C ++ 11中,如果要初始化一个指向NULL的指针,建议您使用nullptr关键字完成此工作。 This answer about nullptr should help you to understand. 有关nullptr的答案应有助于您理解。

I also replace the following code 我也替换下面的代码

typedef enum
{
    WAITING_SYNC,
    WAITING_UBLOX_MSG,
    WAITING_NOVATEL_MSG
} states_t;

By the this one (strongly typed enum since C++11) 通过这个(自C ++ 11起强烈键入的枚举)

enum class states_t : uint8_t {
    WAITING_SYNC,
    WAITING_UBLOX_MSG,
    WAITING_NOVATEL_MSG
};

A short explanation of the enum class 枚举类的简短说明

About the delegating constructor, it seems to be correct. 关于委托的构造函数,这似乎是正确的。 It should be used only in constructor initializer list like you did. 像您一样,仅应在构造函数初始化器列表中使用它。 If this was the problem, maybe the compiler you use doesn't let you use the delegating constructor. 如果这是问题所在,也许您使用的编译器不允许您使用委托的构造函数。 If you are using Visual C++, this answer should help you. 如果您使用的是Visual C ++,则此答案将为您提供帮助。 With GCC 4.7 and higher and clang 3.1 and higher, I'm sure it's working. 对于GCC 4.7和更高版本以及clang 3.1和更高版本,我确定它可以正常工作。

Hope that helps you. 希望对您有帮助。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM