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 という名前のファイルを作成し、その中にコードを入れました。次のコードは、GCC 4.7 および Clang 3.3 で -Wall -Werror -pedantic-errors 属性を使用して正しくコンパイルされました。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
};

enum クラスの簡単な説明

委任コンストラクタについては、正しいようです。あなたがしたように、コンストラクタ初期化子リストでのみ使用する必要があります。これが問題である場合は、使用しているコンパイラが委譲コンストラクターを使用できない可能性があります。Visual C++ を使用している場合は、この回答が役に立ちます。GCC 4.7 以降および clang 3.1 以降では、動作していると確信しています。

お役に立てば幸いです。

于 2013-10-29T22:30:08.457 に答える