当指针处于"私有"状态时,我无法理解如何使用指针。
大多数情况下我不知道如何获取和设置指针的值
我想创建一个没有字符值的头和尾节点。然后创建位于头部和尾部之间的新节点,并将新节点添加到列表末尾(尾部之前)。
代码运行,但当我使用打印功能时它不执行任何操作。
抱歉,如果我的格式错误并且代码太长。
这是我类的代码:
#include <iostream>
using namespace std;
class node
{
public:
node(void)// constructor for empty nodes
{
left_link = NULL;
right_link = NULL;
}
node(char x) // constructor for nodes with given value
: anything(x)
{ }
char get_char() // return character
{
return anything;
}
void setLeftLink(node *left)
{
left_link = left;
}
void setRightLink(node *right)
{
right_link = right;
}
node *getlefttLink()
{
return left_link;
}
node *getRightLink()
{
return right_link;
}
private:
node *left_link;
char anything;
node *right_link;
};
以下是我的函数:
void append(node *&head, node *&tail);
void print(node *head);
void append(node *&head, node *&tail)
{
char c;
cout << "Please enter a single character: ";
cin >> c;
node *current = new node(c);
cout << current->get_char() << endl;
if(head == NULL && tail == NULL)
{
head->setRightLink(current);
tail->setLeftLink(current);
current->setLeftLink(head);
current->setRightLink(tail);
}
else
{
tail->setRightLink(current);
current->setLeftLink(tail);
tail = current;
tail->setRightLink(NULL);
}
}
// print function
void print(node *head)
{
node* temp;
temp = head;
while(temp->getRightLink()!=NULL){
cout<<temp->get_char()<<endl;
temp = temp->getRightLink();
}
}
这是我的主要:
int main()
{
char choice;
node *head = new node;
node *tail = new node;
cout << "Please choose one menu option at a time:n"
<< "1 = Appendn"
<< "2 = Print listn"
<< "3 = Exitnn";
do
{
cout << "Menu option(1-3): ";
cin >> choice;
switch (choice)
{
case '1': append(head, tail); // add to the end of list.
break;
case '2': print(head); // print list
break;
case '3': cout << "end programnn";
break;
default: cout << "try againn";
break;
}
}while(choice != '3');
return 0;
}
private
成员、指针或其他方式,是对象不希望被其他人弄乱或想知道是否有人弄乱的数据。
二传手和吸气手方法允许以受控方式访问private
成员。例如,如果您有一个在任何情况下都不能大于 10 的私有整数,则可以在 setter 中使用代码来检查调用方是否试图强制值超出范围并拒绝请求。
bool setX( int newX)
{
if (newX > 10)
{
return false;
}
else
{
X = newX;
return true;
}
}
现在,该程序不会有任何令人讨厌的惊喜,X == 11会导致超出范围的访问或其他什么。
这是物体的自卫。他们保持对谁将数据设置为什么的控制,并且可以保持一致性。假设您有一个更复杂的情况,在启用 FIR 滤波器的情况下,您无法以每秒超过 10000 个样本的速度对 A/D 进行采样,而不会使 CPU 不足并锁定系统。哎 呦。如果设置筛选器状态或采样率的唯一方法是通过 A/D 管理器对象中的资源库,则该对象可以测试、拒绝和防止灾难(并可能留下一条指向不良参与者的漂亮胖日志消息)。
在实现返回非常量引用或指针的 getter 之前,请仔细考虑。一旦调用方拥有其中之一,他们就可以对返回的数据做任何他们想做的事情。
经验法则是默认偏执:在没有充分理由的情况下不授予对任何数据的访问权限,然后更喜欢通过二传手和获取者进行受控访问。
关于您问题的具体情况。
链接节点的设置器和二传手通常是一个傻瓜赌注。节点很可能无法自行确定链接是否有效。只有列表管理员可以。在这种情况下,对象本身太无知而不知道什么是安全的,因此您必须向另一个知道更多的对象开放内部结构。 friend
在这里很有用,尽管通常最好使节点的链接public
并且永远不允许列表管理器将节点提供给客户端。
很有可能,客户应该对列表的工作原理一无所知。阅读有关耦合的信息。
所以节点应该是完全愚蠢的。这意味着你需要有一个ListManager
类来(duh)管理列表并保护node
免受行为不良的参与者的侵害。
ListManager
包含您的head
,tail
,root
或其他任何内容以及append
和remove
,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
的。现在只有ListManager
可以访问node
并且具有完全访问权限。
ListManager
还需要一个析构函数来处理delete
附加的所有new
ed节点。它还需要一个复制构造函数和一个赋值运算符来使其符合三规则。"什么是三法则?"你问?这是非常重要的。阅读链接以节省将来的调试时间。不遵守三法则会导致堆栈溢出上不成比例的C++问题,进一步夸大这个统计数据是没有意义的。
用法:
int main()
{
ListManager list;
char choice;
std::cout << "Please choose one menu option at a time:n" << "1 = Appendn"
<< "2 = Print listn" << "3 = Exitnn";
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 programnn";
break;
default:
std::cout << "try againn";
break;
}
} while (choice != '3');
return 0;
}
首先,头部和尾部应初始化为 NULL,因为开头什么都没有。
node *head = NULL;
node *tail = NULL;
然后更改要追加的代码,尤其是第一个 if 语句。将代码更改为
if(head == NULL && tail == NULL)
{
head = current;
tail = current;
}
由于您正在启动一个新列表,因此头和尾都是您刚刚插入的同一节点。
最后,在打印函数中更改 while 循环的条件。像这样简单的事情应该有效。
while (temp) {
cout << temp->get_char() << endl;
temp = temp->getRightLink();
}
您想要打印当前节点,即使它没有正确的邻居。