web-dev-qa-db-ja.com

C ++のメソッドシグネチャで使用する場合、typedefをどこに配置すればよいですか?

私はOptionalクラスを使用していますが、これはboostのクラスとよく似ています。意味上の理由から、一部のクラス定義(およびメソッドシグネチャ)で同じ(構造化)タイプの属性を必須からオプションに切り替えました。そこで、関連する各クラスヘッダーファイルに、Optionalの定義と、入力を容易にするためのtypedefを含むヘッダーを含めました( CHANGEコメント);節は次のように読みます:

#include <MyAttrType.h>
#include <Optional.h>                          // CHANGE
typedef Optional<MyAttrType> OptionalAttrType; // CHANGE

class MyClassX
{
// ...

今日、私はプロジェクトでCppcheck 1.68を実行し、このスタイルの警告を受けました:

Typedef 'OptionalAttrType'は、同じ名前のtypedefを非表示にします。

何か悪いことをせずにこれらのスタイルの警告を取り除くにはどうすればよいですか?


備考:

  • MyAttrType自体は現在Optionalから独立しています(オプションが最後に使用されていた間、プロジェクト履歴の早い段階で定義されているため)
  • この目的のためだけに新しいヘッダーを導入することを考えています。しかし、より良いオプションがあるのでしょうか?
  • 同じオプション属性を持つ多くのクラスがあることは、一般に設計が悪いことを示していると思いますが、私の特別なケースではわかりません。コードは現在、より優先度の高い目標を達成するために変更されています。
  • もちろん、MyAttrTypeOptionalAttrType、およびMyClassXは実際の名前ではありません
5
Wolf

私は通常、2つの方法のいずれかを使用します。

  1. 最初の方法は、最初の宣言の場所でtypedefを使用することです。
  2. 2番目の方法は、typedef at each place-of-useを使用し、それをその使用場所にのみ表示することです(それを使用するクラスまたはメソッド内に配置することにより) 。

(1)ラップされる型の近くにtypedefを置きます。

_/* MyAttrType.h */

#include <Optional.h>

// README : See Optional<MyAttrType> at the end of this header

struct MyAttrType
{
    // ....
};

// (put the typedef here)
typedef Optional<MyAttrType> OptionalMyAttrType;

/* ---------------------------- */
/* Every other C++ source files */
#include "MyAttrType.h"

// .... Any code can use OptionalMyAttrType there.
_

(2)typedefを、それを使用する各クラスに対してのみ可視にします。

_/* MyAttrType.h */

namespace my_pod_types
{
    struct MyAttrType { /* ... */ };
}

// (nothing else outside.)

/* ---------------------------- */
/* Every other C++ source files */

#include "MyAttrType.h"
#include "Optional.h"

class MyClassX
{
private:
    typedef Optional<my_pod_types::MyAttrType> OptionalMyAttrType;
public:
    // ...
private:
    OptionalMyAttrType m_optAttr;
};
_

ほとんどの場合、私に関連するテンプレートは_std::unique_ptr_と_std::shared_ptr_のどちらかです。さらに、クラスがいずれかの方法を使用することを決定し、そのスマートポインターラッパーを「MyClassOnePtr」としてtypedefします。ドラコニアンですが、図書館の主な著者は、ほとんどの場合、図書館にとって何が最良かを知っているはずです。

2つのスマートポインターのどちらを優先するかが明らかでない場合は、最初のヘッダーにtypedefを入れません(したがって、選択肢が明らかでない限り、オプション#1は使用しません)。

ほとんどの場合、オプション#2が_Optional<T>_の使用をエンドユーザーから常に保護するわけではないことに気付くでしょう。つまり、アプリケーションロジックは、MyClassXのユーザーに、_Optional<T>_との対話時に対処するよう要求する場合があります。その場合、それを非表示にすることはできません。これは実装の詳細ではありません。それは目に見える表面の一部です。

最後に、C++の制限を認識して、前方宣言する必要があります。つまり、C++が事前に知る必要がある場合があります。

  • ラップされるタイプのサイズ。
  • デフォルトのコンストラクタとデストラクタの存在。
  • 等々。

そのような制限の例については、 Stackoverflowに関するこの質問(_unique::ptr_について) を参照してください。


別のnrelated私が共有したいこと ixrec の回答を読んだ後。

名前空間を使用してクラスを分類しない限り、Doxygen(広く使用されているC++のドキュメントからHTMLジェネレーターへ)で適切に整理されたドキュメントを生成できないことがわかったので、「デフォルトの名前空間には何もない」というポリシーに従いました。これらの名前空間にどのように名前を付けるかは問題ではないようです。 Doxygenがそれらを別個のものと見なし、人間のユーザーがそれについて文句を言わない限り、名前空間のアプローチは問題ありません。

4
rwong

3つのエラーがあります。

  1. ヘッダーは、ビジネスが宣言していないライブラリ専用ではない名前空間で名前を宣言しています。
  2. ライブラリ全体にその定義が1つしかないことを確認していないようです。
  3. そのバグを修正するのではなく、警告を遮断しようとしています。

あなたがすべきことは次のいずれかです:

  1. それをインターフェースの一部にします。
  2. または、ライブラリの名前空間(おそらくネストされた名前空間internalなど)で非表示にします。
  3. または完全に削除して、フルネームを書きます。

オプション1または2を選択する場合は、1つの場所でのみ定義されていることを確認してください。

0
Deduplicator

OptionalAttrTypeがこれらのヘッダーで定義されたパブリックAPIの一部である場合、typedefには別の名前を使用します。

OptionalAttrTypeが、あなたが知らないはずの実装の詳細である場合、これらのヘッダーは、このような衝突を防ぐために名前空間内に配置する必要があります。彼らがしなかったので、どういうわけかこれを回避しなければなりません。

この質問をしているので、将来これらの衝突がさらに発生することが予想されるため、長期的な解決策が必要です。依存するすべてのヘッダーとソースファイルを変更して名前空間またはより一貫性のあるクラス名を使用できない限り、私が考えることができる唯一の一般的な解決策は、何かと衝突する可能性が低いプレフィックスまたはサフィックス(たとえば、OptionalAttrType_TD)を選択して使用を開始することですあなたのすべてのtypedefのためのそれ。

一般的ではありませんが、おそらくより実用的な代替策は、この警告を単に非表示にすることです。 Cppcheckマニュアル の第6章では、そのツールからの特定の警告を抑制する方法をすべて説明しています。

0
Ixrec