2

現在、おおよそ次のようなクラス階層を設計しています。

struct Protocol
{
    // Pass lower-layer protocol as a reference.
    Protocol(Protocol & inLLProtocol) :
        mLLProtocol(inLLProtocol)
    {
    }

    // A protocol "always" has a LLProtocol.
    Protocol & mLLProtocol; 
};


struct Layer1Protocol : Protocol
{
    // This is the "bottom" protocol, so I pass a fake reference.
    Layer1Protocol() : Protocol(*static_cast<Protocol*>(nullptr)) {}
};

参照へのIIRCバインディングは*nullptr、参照がアクセスされない限り安全です。したがって、それを防ぐような方法で Layer1Protocol クラスを設計するのは私の責任です。

すべてのユーザー プロトコル インスタンスそれぞれの下位層プロトコルへの参照を持つようにするため、このアプローチが気に入っています (Layer1Protocol は例外ですが、コア ライブラリの一部です)。これは、ポインターを使用するよりも好ましいと思います。ポインターが導入されると、null ポインターを渡すことが可能になり、実行時にチェックする必要が生じる可能性があり、その結果、多くのポインター チェック コードと時折のバグが発生するからです。

私の参照ベースのアプローチは擁護できると思いますか? それとも、null 参照を使用するのは常に悪い習慣ですか?

4

4 に答える 4

11

*nullptr への参照をバインドする IIRC は、参照がアクセスされない限り安全です。

いいえ、逆参照nullptrは常に未定義の動作です。正しいプログラムに「null 参照」を含めることはできません。

于 2012-05-25T09:55:06.900 に答える
10

書き込みは、未定義の動作を呼び出す を*static_cast<Protocol*>(nullptr)逆参照しています。そんなことは絶対にしてはいけません。結果は、マーフィーが思いつくものなら何でもかまいません。これは「ヌル参照」と呼ばれるものかもしれませんが、プログラムが有効なポインターを逆参照したかのように動作している間に、あなた (男性、AFAIK) が妊娠する可能性もあります。nullptr

したがって、厳密に言えば、「null 参照」はありません。Undefined Behaviorだけがあります。

いずれかのプロトコル クラスは常に低レベルのプロトコルを必要とし、その場合はnullptr(参照で偽装しても) 渡してはなりません。または、常に下位レベルのプロトコルを必要とせず、アクセスする前に下位レベルのプロトコルがあるかどうかを確認する必要があります。この場合、ポインターはデザインの制約をより適切に実装します。

于 2012-05-25T09:55:00.277 に答える
2

あなたのアプローチは、構文を除いて、そして参照アプローチとは異なり、ポインターアプローチがUBを呼び出さないという事実を除いて、ポインターを使用する同等のアプローチとどのように異なりますか?

nullポインターをチェックする必要がないように参照を操作しているが、(違法な)null参照を渡す場合は、参照の利点を否定しています。これで、参照が突然nullになる可能性があるため、ポインターを使用している場合と同じように、おそらくその状態をチェックする必要があります。

あなたが言うように、これらのnull参照のいずれも逆参照されないことを保証できる場合、ポインターを使用する場合も同じ保証が適用されます。

簡単に言うと、ポインタは絶対に避けるべきものではありません。nullが発生する可能性がある状況では、ポインター--periodを使用する必要があります。どこでも(おそらくアサーションを介して)nullポインターをチェックする必要があることを心配しているようですが、ほとんどのアーキテクチャーでは、MMUはとにかくnullポインターを逆参照することを阻止します-これは実際にはアサーションとほぼ同じです。

于 2012-05-25T10:03:38.200 に答える
1

ブーストの「オプションの」クラステンプレートを見たいと思うかもしれません(私は信じています)。オブジェクトを渡すことができますが、生のポインターよりも少し安全な方法で、意図的にデータを提供していないことを指定することもできます。

それは私自身が特に好きなものではありませんが、あなたの要件を満たしていることがわかるかもしれません.

于 2012-05-25T10:08:53.707 に答える