2012-02-13 10 views
1

I持って私の.h/.cppのファイルに次のコード:は、ポインタをストリームの過負荷を説明し、typedefの

.H:

class Foo; 
typedef Foo * pFoo; 

class Foo { 
public: 
    char c; 
}; 
std::ostream& operator<<(std::ostream &out, const Foo &f); 
std::ostream& operator<<(std::ostream &out, const pFoo &f); 

た.cpp:メインで

std::ostream& operator<<(std::ostream &out, const Foo &f) { out << f.c; return out; } 
std::ostream& operator<<(std::ostream &out, const pFoo &f) { out << f->c; return out; } 

Foo f; 
f.c = 'a'; 
std::cout << "As foo object:" << f << std::endl; 
std::cout << "As foo pointer:" << &f << std::endl; 

:私は、次のコードを実行するとき

As foo object:a 
As foo pointer:0x7fff5fbff980 

私はあなたがオーバーロードすることはできません知っている:私は出力を得る代わりに

#define pFoo Foo* 

:で、例えば、私は私のtypedefを交換する場合は、

As foo object:a 
As foo pointer:a 

しかし:私は出力を得ます組み込み型の演算子。 typedefは実際に新しいタイプを作成していますか、それとも既存のタイプのエイリアスですか?答えは、新しいタイプを作成しているようです。私は基本的に行動の違いの間のより深い説明を探しています。 (私は、生産コードでこれをやろうとしていないよ。)

+0

IMHO、あなたは "#define"と "typedef"を使って "ポインタ型"を作成する方が良いでしょう。ポインターを宣言するために必要なところで '*'を使うのがはるかに明確で、このような驚きを避けることができます。また、[Linux Coding Standards](http://www.kernel.org/doc/Documentation/CodingStyle)は、typedefでポインタ型を作成することを禁止しています。第5章:構造体やポインタに 'typedef'を使うのは間違いです*ソースで' vps_t a; 'が見えるときはどういう意味でしょうか?対照的に' struct virtual_container * a; 'あなたは実際に' a'が何であるかを知ることができます。 –

+0

私は同意しない。私は、コードのさまざまなバリエーションを使って、物事がどのように働いているかを見て回り、私が見ていた違いを説明できませんでした。あなたのコメントは、さまざまな理由でこのページを見ている人のためにここにあることが正しいか、もちろん正しいです。 –

答えて

2

はtypedefで本当に新しいタイプを作成している、またはそれは、既存のタイプのためだけのエイリアスですか?

typedefはタイプのエイリアスまたは同義語を紹介します。

typedefを使用すると、const pFooFooへのconstのポインタになります。あなただけの定義使用してFoo*pFooを交換
は、関数の引数はconst Fooへのポインタである、const Foo*です。

Foo *p = &f; 
std::cout << *p << std::endl; 
+0

そして、後者の場合、彼はそれに一致する 'operator <<'を持っていないので、コンパイラは 'void *'のオーバーロードを選択しました。 –

+0

右'Foo * const&f'は私に望ましい結果を与えました。私は違いを完全に見落としていた。 –

1

に:あなたは常にポインタデリファレンス、2番目のオーバーロードの必要があってはならないことができますように、その

const Foo * & 
Foo const * & 
Foo * const & 

注:

パラメータの型として以下のバリエーションを試してみてください2番目のケースはoperator <<オーバーロードに一致しないため、標準のポインタが使用されます。

typedef Foo * pFoo;を使用すると、Foo*の別名はpFooになります。次に、const pFoopFoo* const,Fooへの定数ポインタを意味するconst (pFoo *)を意味します。 &fconst pFoo*と一致するため、2番目のオーバーロードが使用されます。

#define pFoo Foo *は単にpFoo' withはFoo * . As a rfesultのconst pFoo expands intoのconst Fooの* , _pointer to constant Fooを再生します。 &fこれはmacthではありません。そのため、ポインタの標準的なオーバーロードが使用されています。

関連する問題