private
メンバー、ポインタまたはその他のものは、オブジェクトが誰かに混乱したくない、または誰かが混乱しているかどうかを知りたいデータです。
セッターメソッドとゲッターメソッドは、private
メンバへのアクセスを制御された方法で許可します。たとえば、決して十数を超えることができないプライベート整数がある場合、呼び出し側が値を範囲外に強制して要求を拒否しようとしているかどうかをチェックするコードをセッターに含めることができます。
bool setX(int newX)
{
if (newX > 10)
{
return false;
}
else
{
X = newX;
return true;
}
}
今プログラムは、範囲外のアクセスまたは任意の原因となるXの== 11で任意の厄介な驚きを持つことができません。
これはオブジェクトの自己防御です。彼らは、誰がデータを何に設定し、一貫性を維持できるかを管理しています。 CPUを枯渇させずにシステムをロックすることなく、FIRフィルタを有効にして1秒間に10000を超えるサンプルでA/Dをサンプリングできないという複雑なケースがあるとします。うわー。 Filter状態またはサンプリングレートを設定する唯一の方法がA/Dマネージャオブジェクトのセッターを介している場合、オブジェクトはテストと拒否を行い、災害を防ぎます(悪い俳優を指すファットログメッセージを残すこともできます)。
定数でない参照やポインタを返すゲッターを実装する前に、非常に難しいと思ってください。呼び出し元にどちらかがあると、返されたデータで必要な処理を実行できます。
親切な理由なしにデータへのアクセスを許可しないで、セッターとゲッターを介して制御されたアクセスを優先するのがパラノイアです。
問題の詳細については、
リンクノードのゲッターとセッターは、しばしば嫌な賭けです。リンケージが有効である場合、ノードは自分自身を決定できない可能性が最も高い。リストマネージャのみが可能です。これは、オブジェクト自体が何が安全であるかを知るにはあまりにも無知であるため、より多くを知っている別のオブジェクトに内部を開く必要があります。 friend
は便利ですが、ノードのリンクpublic
を作成し、リストマネージャがノードをクライアントに与えることを許可しないことがよくあります。
オッズは良好です。クライアントはリストの仕組みについて絶対に何も知ってはいけません。カップリングで読む。
したがってノードは完全に愚かでなければなりません。つまり、ListManager
クラス(リスト)を管理して、リストを管理し、悪い振る舞いをするアクターからnode
を保護する必要があります。
ListManager
はあなたのhead
、tail
、append
とremove
とともにroot
または何、print
およびその他のリスト管理メソッドが含まれています。いかなる状況下でも、これらの関数のいずれも呼び出し元にnode
を明らかにしませんが、呼び出し元にリストを損傷させることなくノードを参照するためのハンドルまたはイテレータを返すことはできません。イテレータは独自の質問にふさわしいトピックであり、すでにかなりの数のものがあります。
上記を説明するコードの一部が順番です。私が見つけた論理的な問題はマークしましたが、修正されていません。これがコンパイルされると(C++ 11を有効にして)さらに多くなることがありますが、実行していません。
class ListManager
{
private:
class node
{
public:
node *left_link = nullptr; // recommendation: immediately set or NULL all
// pointers unless you have a well documented
// reason not to and profiling to back it up.
// The time you save can be enormous.
char anything;
node *right_link = nullptr;
};
node *head = nullptr;
node *tail = nullptr;
public:
void append(char c) // head and tail not required ListManager members
{
/* removed because the append function should append and only append.
* If you want to read data from the user, call a read function first
* and pass it read character in to append
* Do one thing and do it well. Every time you add behaviours to a
* function, you make it harder to debug. For example, what happens to
* the linked list if you fail to read a character? That shouldn't be
* append's problem.
char c;
std::cout << "Please enter a single character: ";
std::cin >> c;
*/
node *current = new node();
current->anything = c;
//std::cout << current->anything << std::endl; removed for same reason as above.
// think on this: how can head and tail NOT both be NULL at the same time?
// if you find a way, you have a bug that needs fixing.
if (head == nullptr && tail == nullptr)
{
// If head is NULL, it has no right_link to assign. This will fail horribly.
head->right_link = current;
tail->left_link = current;
current->left_link = head;
current->right_link = tail;
/* Consider instead
head = current;
tail = current;
*/
}
else
{
tail->right_link = current;
current->left_link = tail;
tail = current;
tail->right_link = nullptr; // don't need to do this. node constructor
// ensures current->right_link is NULL
}
}
// print function
void print() // no parameters required. head is ListManager member
{
node* temp;
temp = head;
// Again, if head is NULL, temp will be NULL and there will be no right_link
// consider instead
// while (temp != nullptr)
while (temp->right_link != nullptr)
{
std::cout << temp->anything << std::endl;
temp = temp->right_link;
}
}
};
node
が右ListManager
に組み込まれており、private
ですか注意してください。 node
にアクセスできるのはListManager
で、完全なアクセス権があります。
ListManager
には、追加されたnew
edノードのすべてを処理するデストラクタも必要です。また、3のルールに準拠させるために、コピーコンストラクタと代入演算子が必要です。 "What is The Rule of Three?"お尋ねしますか?非常に重要です。将来のデバッグのためにリンクを読んでください。 3つのルールに従わないと、スタックオーバーフローに関するC++の質問が不規則になります。この統計をさらに膨らませることはできません。
使用法:
int main()
{
ListManager list;
char choice;
std::cout << "Please choose one menu option at a time:\n" << "1 = Append\n"
<< "2 = Print list\n" << "3 = Exit\n\n";
do
{
std::cout << "Menu option(1-3): ";
std::cin >> choice;
switch (choice)
{
case '1':
list.append('a'); // add to the end of list.
break;
case '2':
list.print(); // print list
break;
case '3':
std::cout << "end program\n\n";
break;
default:
std::cout << "try again\n";
break;
}
} while (choice != '3');
return 0;
}
私はあなたの問題は、変数がプライベートであることとは何かを持っている疑い。 – immibis
***コードは実行されますが、print関数を使用すると何もしません。***あなたのアドバイスは、デバッガの使用方法を学ぶことです。変数を見ているコードを一歩。 – drescherjm
あなたはリンクリスト概念かC++ポインタを誤解しています。要素がない場合は、新しいノードを作成しなければなりません。新しいノードはheadとtailの両方になり、それを 'nullptr'に左右隣に設定します。'append'関数内の' if'文を見直してください。**未定義の動作**があります。 – K117