C++ 类的链接列表,如何在转换时调用字符串?
我想知道如何在类C++ 类的链接列表,如何在转换时调用字符串?,c++,list,class,hyperlink,C++,List,Class,Hyperlink,我想知道如何在类BoxClass的链接列表中调用toString()方法BoxClass有一个double长度、宽度和高度 我的BoxClass: class BoxClass{ private: double length; double width; double height; public: // Default constructor w/ no parameters BoxClass(){ length = 0;
BoxClass
的链接列表中调用toString()
方法BoxClass
有一个double
长度
、宽度
和高度
我的BoxClass:
class BoxClass{
private:
double length;
double width;
double height;
public:
// Default constructor w/ no parameters
BoxClass(){
length = 0;
width = 0;
height = 0;
}
// Constructor with arguments
BoxClass(double boxLength, double boxWidth, double boxHeight){
length = boxLength;
width = boxWidth;
height = boxHeight;
}
// Setters and Getters
void setLength(double boxLength){
length = boxLength;
}
double getLength(){
return length;
}
void setWidth(double boxWidth){
width = boxWidth;
}
double getWidth(){
return width;
}
void setHeight(double boxHeight){
height = boxHeight;
}
double getHeight(){
return height;
}
// Returns the volume of the boxes
double Volume(){
return (length * width * height);
}
// toString method for boxes, returns "(length) x (width) x (height) string
string toString(){
return ("(" + to_string(length)+ "x" + to_string(width) + "x" + to_string(height) + ")");
}
}; // End of BoxClass() class
LinkNode.h
//Template ListNode class definition.
#ifndef LINKNODE_H
#define LINKNODE_H
template <typename T> class LinkList;
template <typename T> class LinkNode{
friend class LinkNode <T>;
public:
LinkNode(const T &);
T getData()const;
T data;
LinkNode <T> *nextPtr;
};
template <typename T> LinkNode <T>::LinkNode(const T &info):data(info), nextPtr(NULL){
// Empty body
}
template <typename T>T LinkNode<T>::getData()const{
return data;
}
#endif
//Template LinkList class definition.
#ifndef LINKLIST_H
#define LINKLIST_H
#include <iostream>
#include "LinkNode.h"
using namespace std;
template<typename T> class LinkList {
public:
LinkList();
void addNode(const T &);
void insertNode(const T &);
bool isEmpty() const;
void print() const;
private:
LinkNode<T>*firstPtr;
LinkNode<T>*getNewNode(const T &);
};
template<typename T>LinkList<T>::LinkList() :firstPtr(NULL) {
// Empty body
}
template <typename T>void LinkList<T>::insertNode(const T &value) {
LinkNode<T>*newPtr = getNewNode(value);
bool inserted = false;
if (isEmpty() || (newPtr->data < firstPtr->data)) {
newPtr->nextPtr = firstPtr;
firstPtr = newPtr;
// cout << " " << newPtr->data << " inserted at front of list.\n";
printf(" %.2f inserted at front of list.\n", newPtr->data);
} else {
LinkNode<T>*currentPtr = firstPtr;
while (currentPtr->nextPtr && !inserted) {
if (newPtr->data < currentPtr->nextPtr->data) {
// cout << " " << newPtr->data << " inserted before " << currentPtr->nextPtr->data << ". " << endl;
printf(" %.2f inserted before %.2f.\n", newPtr->data, currentPtr->nextPtr->data);
newPtr->nextPtr = currentPtr->nextPtr;
currentPtr->nextPtr = newPtr;
inserted = true;
} else {
currentPtr = currentPtr->nextPtr;
}
}
if (!inserted) {
currentPtr->nextPtr = newPtr;
printf(" %.2f inserted at the end of list.\n", newPtr->data);
}
}
}
template<typename T>bool LinkList<T>::isEmpty()const {
return firstPtr == NULL;
}
template<typename T>LinkNode<T>*LinkList<T>::getNewNode(const T &value) {
return new LinkNode<T>(value);
}
template<typename T>void LinkList<T>::print()const {
// To list off nodes
int counter = 1;
if (isEmpty()) {
cout << "No boxes in list!\n";
} else {
LinkNode<T>*currentPtr = firstPtr;
cout << "Your boxes in increasing order of volume is:\n";
// while (currentPtr) {
while (currentPtr != NULL) {
// Output as "#. (length x width x height)
cout << counter << ". " << currentPtr->data << endl;
printf(" %i. %.2f\n", counter, currentPtr->data);
currentPtr = currentPtr->nextPtr;
counter++;
}
}
}
#endif
LinkList.h print()方法
template<typename T>void LinkList<T>::print()const {
// To list off nodes
int counter = 1;
if (isEmpty()) {
cout << "No boxes in list!\n";
} else {
LinkNode<T>*currentPtr = firstPtr;
cout << "Your boxes in increasing order of volume is:\n";
// while (currentPtr) {
while (currentPtr != NULL) {
// Output as "#. (length x width x height)
cout << counter << ". " << currentPtr->data << endl;
printf(" %i. %.2f\n", counter, currentPtr->data);
currentPtr = currentPtr->nextPtr;
counter++;
}
}
}
templatevoid链接列表::print()常量{
//列出节点
int计数器=1;
if(isEmpty()){
cout当您编写模板类LinkNode{
时,您特别声明您的节点类对于它包含的节点类型没有内置的知识
您没有向我们展示您的链接列表
类,但显然,同样的事情也适用于它:因为它由链接节点
组成,它还必须接受类型为
的泛型参数,所以它也不能具有
的实际类型的内置知识
因此,你不能突然引入一种拥有这种知识的方法,它没有意义,“它不计算”
您需要做的是在其他地方添加您的print()
方法,并使其接受LinkList
。然后,它将能够以LinkNode
的形式查看LinkNode
,并能够调用LinkNode.data.toString()
问题在于,您的链接列表
类的实现无法让客户端代码在循环中遍历列表的每个节点。如果我们不想打印,但对每个框执行其他操作,该怎么办
此外,如果我有一个链接列表
,并且在调用print()
时看到文本,这看起来会很奇怪:
“您的箱子按体积递增的顺序是:;
我会说,“什么盒子?什么体积?我有小部件,不是盒子”
一个更完整的实现应该是这样的(注意:这还没有被编译。这是为了给你应该做什么的要点):
请注意print
如何不再是LinkList
的成员。此外,请注意typedef
为客户端使用的LinkNode
指针提供了一个“好”的名称。注释应该是不言自明的
我不想通过引入“实”迭代器(即重载的++
)使代码过于复杂,但该操作符将替换链接列表:::next()
函数调用。我把它留给您作为一个额外的练习。我不太理解…那么,问题是否存在于我的节点中?您的意思是,我的节点类根本不知道如何处理我的BoxClass
方法()
?。如果是,这是否意味着我的LinkNode.h必须有一个print()
方法,该方法接受LinkList
作为参数,该参数反过来允许我调用toString()
?@user3499789如果您不能使用公共
界面对链接列表进行迭代,则链接列表是无用的。如果我想对列表中的每个节点执行其他操作,而不是打印,该怎么办?如果我不想打印,而是想将数据保存到文件中,或者对列表中的每个节点执行更复杂的操作,您会知道一切吗链表类的用户可能想要处理列表中的数据?当然不是。因此,您当前的实现是不完整的——它没有为链表类外部的代码提供遍历每个节点的方法。是的,我就是这么说的,除了“LinkNode.h”部分。print()方法不属于链接节点,也不属于链接列表。它必须转到其他位置。基本上,您的实现缺少迭代器的概念。在链接列表之外,我应该可以说“获取第一个节点”,然后“获取下一个节点”然后循环。是的,在内部,您现在可以在列表中执行此操作,但在公开情况下,无法执行此操作。因此,这是您需要实现的。
//Template LinkList class definition.
#ifndef LINKLIST_H
#define LINKLIST_H
#include <iostream>
#include "LinkNode.h"
using namespace std;
template<typename T> class LinkList {
public:
LinkList();
void addNode(const T &);
void insertNode(const T &);
bool isEmpty() const;
void print() const;
private:
LinkNode<T>*firstPtr;
LinkNode<T>*getNewNode(const T &);
};
template<typename T>LinkList<T>::LinkList() :firstPtr(NULL) {
// Empty body
}
template <typename T>void LinkList<T>::insertNode(const T &value) {
LinkNode<T>*newPtr = getNewNode(value);
bool inserted = false;
if (isEmpty() || (newPtr->data < firstPtr->data)) {
newPtr->nextPtr = firstPtr;
firstPtr = newPtr;
// cout << " " << newPtr->data << " inserted at front of list.\n";
printf(" %.2f inserted at front of list.\n", newPtr->data);
} else {
LinkNode<T>*currentPtr = firstPtr;
while (currentPtr->nextPtr && !inserted) {
if (newPtr->data < currentPtr->nextPtr->data) {
// cout << " " << newPtr->data << " inserted before " << currentPtr->nextPtr->data << ". " << endl;
printf(" %.2f inserted before %.2f.\n", newPtr->data, currentPtr->nextPtr->data);
newPtr->nextPtr = currentPtr->nextPtr;
currentPtr->nextPtr = newPtr;
inserted = true;
} else {
currentPtr = currentPtr->nextPtr;
}
}
if (!inserted) {
currentPtr->nextPtr = newPtr;
printf(" %.2f inserted at the end of list.\n", newPtr->data);
}
}
}
template<typename T>bool LinkList<T>::isEmpty()const {
return firstPtr == NULL;
}
template<typename T>LinkNode<T>*LinkList<T>::getNewNode(const T &value) {
return new LinkNode<T>(value);
}
template<typename T>void LinkList<T>::print()const {
// To list off nodes
int counter = 1;
if (isEmpty()) {
cout << "No boxes in list!\n";
} else {
LinkNode<T>*currentPtr = firstPtr;
cout << "Your boxes in increasing order of volume is:\n";
// while (currentPtr) {
while (currentPtr != NULL) {
// Output as "#. (length x width x height)
cout << counter << ". " << currentPtr->data << endl;
printf(" %i. %.2f\n", counter, currentPtr->data);
currentPtr = currentPtr->nextPtr;
counter++;
}
}
}
#endif
template<typename T> class LinkList {
public:
LinkList();
void addNode(const T &);
void insertNode(const T &);
bool isEmpty() const;
// this is what you're missing from the current implementation
typedef LinkNode<T>* Iterator;
Iterator begin() { return firstPtr; }
Iterator next(Iterator ptr) { return ptr->nextPtr; }
Iterator end() { return NULL; }
private:
LinkNode<T>* firstPtr;
LinkNode<T>* getNewNode(const T &);
};
LinkList<BoxClass> boxList;
//...
void print()
{
if (boxList.isEmpty())
cout << "No boxes in list!\n";
else
{
int counter = 1;
cout << "Your boxes in increasing order of volume is:\n";
// get first box
LinkList<BoxClass>::Iterator curBox = boxList.begin();
// loop until no more boxes
while (curBox != boxList.end())
{
// now use curBox to do whatever you want with this box
BoxClass& b = curBox->getData();
cout << counter << ". " << b.toString();
// go to the next box
curBox = boxList.next(curBox);
counter++;
}
}
}