##『More Effective C+』-基礎議題
4273 ワード
More Effective C++
一、pointersとreferencesをよく区別する
1.1. 初期化
ポインタは初期化せずに、参照は初期化する必要があります.
参照にnull referenceがない、ポインタをNULLにすることができる.
1.2. こうりつ
null referenceは存在しないため、参照使用前にその有効性をテストする必要はなく、ポインタよりも効率が高い.
1.3. しこう
ポインタは、指すオブジェクトを変更し、referenceは常に最終的に指すオブジェクトを指します.
異なる時間に異なるオブジェクトを指し、ポインタを使用します.オブジェクトを表すと変更できません.referenceを使用します.たとえばoperator[]オペレータは、リファレンスを使用します.戻りポインタが値を割り当てるときに次のように書く必要がある場合は、直感的ではなく、誤解を生みやすい.
二、C++変換オペレータを使用することが望ましい
2.1. 新しいモデルチェンジ
2.2. reinterpret_cast
2.3. 新しいものの代わりに古いものを使うと、アップグレードが容易になります.
新式の転換は長くて臭いが、新式の転換を使うのはもっとはっきりしていて、できるだけ転換の使用を減らすことができます.
三、配列を絶対に多態(Polymorphism)で処理しない
3.1. マルチステート配列に存在する問題
サブクラスの配列を多態化しようとすると,サブクラスの大きさが親クラスの大きさに解析されるため,所望の結果が得られないことが多い.これにより予測不可能な結果が生じる.
同様に配列削除を行う場合も同様に問題が発生するため,配列とマルチステートは一緒に使用しない.
このエラーは、「特定のクラスは別の特定のクラスから継承しないでください」という条項33に記載されていることを忘れないでください.
四、必要でなければdefault constructorsを提供しない
4.1. 無中生有
一部のクラスは「無中生有」で生成できるが、一部のクラスは「無中生有」ではない.このような生成の対象は意味がないからだ.例えば、1つの通信帳フィールドの
4.2.
次の配列を定義するとき、タイプ配列 それらは多くの
4.3. デフォルトのコンストラクション関数に存在する問題の提供他のメンバーは、IDが存在するかどうかを確認し、他の は
#@author: gr
#@date: 2015-05-11
#@email: [email protected]
一、pointersとreferencesをよく区別する
1.1. 初期化
ポインタは初期化せずに、参照は初期化する必要があります.
参照にnull referenceがない、ポインタをNULLにすることができる.
// 0,NULL,nullptr
char *str = 0;
int a = 1;
// ,int &b;
int &b = a;
1.2. こうりつ
null referenceは存在しないため、参照使用前にその有効性をテストする必要はなく、ポインタよりも効率が高い.
void print(const double& rd)
{
cout << rd; //
}
void print(const double* rd)
{
if (*rd)
cout << rd; //
}
1.3. しこう
ポインタは、指すオブジェクトを変更し、referenceは常に最終的に指すオブジェクトを指します.
string s1("aaa");
string s2("bbb");
string& rs = s1;
string *ps = &s2;
rs = s2; // , s1, s1
ps = &s1; // , s1
異なる時間に異なるオブジェクトを指し、ポインタを使用します.オブジェクトを表すと変更できません.referenceを使用します.たとえばoperator[]オペレータは、リファレンスを使用します.戻りポインタが値を割り当てるときに次のように書く必要がある場合は、直感的ではなく、誤解を生みやすい.
vector<int> a(10);
a[5] = 2; //
*a[5] = 2; //
二、C++変換オペレータを使用することが望ましい
2.1. 新しいモデルチェンジ
static_cast<type>(expression) //
const_cast<type>(expression) //
dynamic_cast<type>(expression) // , , , null
reinterpret_cast<type>(expression) // ,
2.2. reinterpret_cast
typedef void (*FuncPtr)();
FuncPtr funcPtrArray[10];
int doSomething(); // doSomething funcPtrArray
funcPtrArray[0] = &doSomething; // , ,
funcPtrArray[0] = reinterpret_cast<FuncPtr>(&doSomething);
2.3. 新しいものの代わりに古いものを使うと、アップグレードが容易になります.
#define static_cast(TYPE, EXPRESSION) ((TYPE) (EXPRESSION))
#define const_cast(TYPE, EXPRESSION) ((TYPE) (EXPRESSION))
新式の転換は長くて臭いが、新式の転換を使うのはもっとはっきりしていて、できるだけ転換の使用を減らすことができます.
三、配列を絶対に多態(Polymorphism)で処理しない
3.1. マルチステート配列に存在する問題
class BST{...};
class BalancedBST : public BST{...};
void printBSTArray(ostream& s, const BST array[], int numElements)
{
for (int i = 0; i < numElements; ++i)
{
s << array[i];
}
}
BST BSTArray[10];
printBSTArray(cout, BSTArray, 10); //
BalancedBST bBSTArray[10];
printBSTArray(cout, bBSTArray, 10); // ,
サブクラスの配列を多態化しようとすると,サブクラスの大きさが親クラスの大きさに解析されるため,所望の結果が得られないことが多い.これにより予測不可能な結果が生じる.
同様に配列削除を行う場合も同様に問題が発生するため,配列とマルチステートは一緒に使用しない.
このエラーは、「特定のクラスは別の特定のクラスから継承しないでください」という条項33に記載されていることを忘れないでください.
四、必要でなければdefault constructorsを提供しない
4.1. 無中生有
一部のクラスは「無中生有」で生成できるが、一部のクラスは「無中生有」ではない.このような生成の対象は意味がないからだ.例えば、1つの通信帳フィールドの
class
は、外部から指定された人名が得られなければ、生成されたオブジェクトは意味がありません.これらのオブジェクトは、default constructor
を提供するべきではありません.4.2.
default constructor
の欠如による問題次の
EquipmentPiece
のように、デフォルトの構造関数はなく、いくつかの問題が発生します.class EquipmentPiece{
public:
EquipmentPiece(int IDNumber); // ctors, defalut ctors
};
EquipmentPiece bestPiece[10]; // , EquipmentPiece ctors
EquipmentPiece *bestPieces = new EquipmentPiece[10]; //
を生成できません.この問題を解決するには、オブジェクト配列ではなくポインタ配列を使用します.typedef EquipmentPiece* PEP;
PEP bestPiece[10]; // , 10
PEP *bestPieces = new PEP[10]; //
for (int i = 0; i < 10; ++i)
bestPieces[i] = new EquipmentPiece( ID Number );
template-based container classes
には適用されず、これらのcontrainer
はインスタンス化の目標がdefault constructors
であることを望んでいる.template <typename T>
class Array{
public:
Array (int size);
private:
T *data;
};
template <typename T>
Array<T>::Array(int size)
{
data = new T[size]; // , default ctors
}
の解決策は、template
を慎重に設計し、default ctors
に対する需要を解消することである.たとえば、vector
はデフォルトのコンストラクション関数を必要としません.virtual base classes
の場合、すべての派生クラスがvirtual base class
のconstructors
引数を提供する必要があるという問題があります.4.3. デフォルトのコンストラクション関数に存在する問題の提供
member function
を複雑にする必要がある.class
の効率に影響する.