4

我尝试实现 C++11 功能(我已将此答案用作参考Can I call a constructor from another constructor (do constructor chaining) in C++?)。显然,我做错了,但我不明白为什么。

我在以下代码中收到了几个警告:

  • 成员_output未在此构造函数中初始化
  • 成员_protocol_scanner未在此构造函数中初始化
  • 成员_state未在此构造函数中初始化
  • 成员_source未在此构造函数中初始化

这是代码:

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

1 回答 1

2

我看看你的代码,我改变了一些东西。我创建了一个名为 Test1.hpp 的文件并将您的代码放入其中。以下代码使用带有 -Wall -Werror -pedantic-errors 属性的 GCC 4.7 和 Clang 3.3 正确编译。让我们看看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

请注意,我添加了一个名称空间和您使用的其他一些类。由于我不知道它们的定义,所以我让它们为空以使其正常工作。现在,让我们回顾一下这段代码。

在 C++11 中,如果你想初始化一个指向 NULL 的指针,我建议你使用nullptr关键字来完成这项工作。这个关于 nullptr 的答案应该可以帮助您理解。

我还替换了以下代码

typedef enum
{
    WAITING_SYNC,
    WAITING_UBLOX_MSG,
    WAITING_NOVATEL_MSG
} states_t;

通过这个(自 C++11 以来的强类型枚举)

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

枚举类的简短解释

关于委托构造函数,它似乎是正确的。它应该像你一样只在构造函数初始化列表中使用。如果这是问题所在,那么您使用的编译器可能不允许您使用委托构造函数。如果您使用的是 Visual C++,这个答案应该对您有所帮助。对于 GCC 4.7 及更高版本和 clang 3.1 及更高版本,我确信它可以正常工作。

希望对您有所帮助。

于 2013-10-29T22:30:08.457 回答