1

私は C++ でライブラリを作成しており、モジュールで動作する関数がいくつかあります。例は次のようになります。

void connect(Module *a, Module *b);

問題は、関数が参照も受け入れると便利な場合があることです (モジュールの一部はスタックに割り当てられ、一部はヒープに割り当てられ、すべての &s と *s はすぐに退屈で面倒になります)。

これで、参照を受け取り、それらをポインターに変換して元の関数を呼び出すインライン関数ができました。

inline void connect(Module &a, Module &b){
    connect(&a, &b);
}

私はこのソリューションがあまり好きではありません。いくつかの関数を追加すると、多くのコードを作成、読み取り、コンパイルする必要があるためです...

考えていたもう 1 つのことは、Module::operator Module *()hust return を追加することthisです。

これについてどう思いますか?私が見逃した壮大な失敗の可能性はありませんか?

ありがとう。

4

8 に答える 8

14

で関数を呼び出さないのはなぜですか

connect(&a, &b);

インライン関数のように、参照で呼び出す必要があるときはいつですか? これにより、関数がポインターを受け取り、 と がポインターではないことが非常に明確になりaますb。あと2文字入力するだけです。

于 2009-04-10T14:47:24.710 に答える
8

演算子のオーバーロードを使用するたびに、壮大な失敗の可能性が高まります。問題は、あなた*が標準的なポインター演算子として意図していないことを知っていることですが、あなたのコードを素朴に読んでいる人はそうではありません。

最善の解決策は、コードに戻ってリファクタリング/再考することです。そのため、同じ操作に 2 つのインターフェイスは必要ありません。

于 2009-04-10T14:47:28.877 に答える
6

あなたのケースでそれが良いアイデアかどうかはわかりませんが、一般的には引数アダプターを使用できます:

struct ModulePtrOrRef
{
  Module * m_p;
  Module(Module * p) : m_p(p) {}
  Module(Module & p) : m_p(&p) {}
}

void connect(ModulePtrOrRef a, ModulePtrOrRef b)
{
  connect_impl(a.m_p, b.m_p);
}
于 2009-04-10T15:14:26.750 に答える
4

あなたが観察したように、ポインタまたは参照のいずれかを取るために関数をオーバーロードすることができますが、私は単なる利便性の理由でそうすることに抵抗し、1つの関数に固執します-これはすべての主要なライブラリがどのように機能するかです。

その関数で使用する引数の種類はどれですか?それは異なります-私の個人的なガイドライン:

  • NULLオブジェクトが意味をなす場合は、ポインタを使用してください。

  • 渡されるオブジェクトが通常動的に作成されるという一般的なユースケースの場合は、ポインターを使用します。

  • 実装が内部でポインターを使用する場合は、ポインターを使用します。

  • それ以外の場合は、参照を使用します。

于 2009-04-10T14:49:51.367 に答える
3

私は常に、Google の C++ スタイル ガイドに記載されている規則に従います。

http://google-styleguide.googlecode.com/svn/trunk/cppguide.xml#Reference_Arguments

これは基本的に、 const & と * のみを他のすべてに使用することを示しています。どのパラメーターが変更できない入力 (const の &) で、どのパラメーターが変更されるか (*) を明確にするのに役立つと思います。このような規則に従えば、ソース コードを掘り下げる必要がなくなります。

ポインターはまったく悪いものではないので、避ける理由はありません。実際、ほとんどの場合、"." の代わりに "->" を使用することを意味するだけです。これは見栄えが良く、より明確なコードを書く価値があります。

于 2009-04-10T15:26:53.010 に答える
1

私はこのようなことをするのは非常に気が進まないでしょう - 使用するのが混乱するインターフェースになる可能性があります.

一般に、const 参照を使用するインターフェイスを好みますが、渡されたオブジェクトが変更される場合は、インターフェイスのユーザーに、渡されるオブジェクトが変更される可能性があることを示すため、非 const 参照よりもポインターを好む傾向があります。変更されます。

于 2009-04-10T14:48:12.417 に答える
1

2 つの関数が必要な理由は、モジュールへのポインターがモジュールへの参照とは基本的に異なる型であるためです。それを回避することはできません。

私にとって、ポインタは悪いです。いつも。何かへの参照ではなく、何かのアドレスが必要な場合にのみ使用してください。また、オブジェクトの実際のアドレスが必要になることはめったにありません。私は次のことをします:

  1. ポインターベースの関数を参照ベースの関数に変換します。
  2. 不要なポインターの使用を停止します。ポインター参照は絶対に避けるべきです。

また、const-ness を調査することもできます。

于 2009-04-10T14:49:13.443 に答える
0

パブリック API ではインラインを避けます。

const & は、可能であれば & または * よりも優先されます

これらがどのように接続されるのか、「a」と「b」がどのような関係にあるのか、私にはわかりません

void connect(Module *a, Module *b);

モジュールインターフェースをより明示的に再配置することは理にかなっていますか

Module a;
a.connectOutput(b);

パラメータに名前を付けると、コンテキストに役立ちます;)

于 2009-04-10T15:09:00.947 に答える