简体   繁体   中英

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++? ). 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
  • Member _protocol_scanner was not initialized in this constructor
  • Member _state was not initialized in this constructor
  • Member _source was not initialized in this constructor

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. The following code compiled correctly with GCC 4.7 and Clang 3.3 with the -Wall -Werror -pedantic-errors attributes. Let's see what's the contain of the HPP file.

#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. This answer about nullptr should help you to understand.

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)

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. With GCC 4.7 and higher and clang 3.1 and higher, I'm sure it's working.

Hope that helps you.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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