c++ - 队列示例中的范围/可见性有困难的新 C++ 编码器
问题描述
全部,
上周我问了一个问题,我感谢您在回答时的宽容。我总体上是一个没有经验的编码员,但我一生中的大部分时间都在涉足。这是我上过的最难的语言/课程,它让我发疯,我无法理解其中的一些概念。我做了很多谷歌搜索,发现了一些有用的东西,但从来没有足够相似的东西来解决我遇到的问题。
另外:我对 SO 界面不太熟悉,所以上次不确定如何将答案“标记”为最好的,以表彰那些提供帮助的人。我没有看到回应其他较小评论的方法。这里有很多,但我想为你们花时间帮助他人的人做正确的事。
任务是创建一个包含五个文件的队列类,如下所述:
QueueItem.h包含 QueueItem 的类定义
QueueItem.cpp包含 QueueItem 的成员函数实现。
Queue.h包含 Queue 的类定义。
Queue.cpp包含 Queue 的成员函数实现。
main.cpp包含 main() 测试函数。
队列.h
#pragma once
#include "QueueItem.h"
class Queue {
public:
Queue(); // ctor inits a new empty Queue
~Queue(); // dtor erases any remaining QueueItems
void addItem(const char* pData);
void removeItem();
void print();
void erase();
private:
QueueItem* _pHead; // always points to first QueueItem in the list
QueueItem* _pTail; // always points to the last QueueItem in the list
int _itemCounter; // always increasing for a unique id to assign to each new QueueItem
};
在下面的 Queue.cpp 中,有两个地方我认为代码应该是 _pTail->_pNext 或 _pTail._pNext。如果它是 ->,那么我得到C++ 成员(在第 21 行声明)不可访问,但使用 . 给出C++ 表达式必须具有类类型。这绝对是我认为这是我不理解的概念性事物的地方之一,因为我认为它应该是 -> 但不知道如何使其易于访问。
队列.cpp
#include "Queue.h"
#include "QueueItem.h"
#include <iostream>
using namespace std;
void Queue::addItem(const char* pData) {
// dynamically create and init a new QueueItem object
QueueItem* pItem = new QueueItem(pData, ++_itemCounter);
if (0 == _pHead) // check for empty queue
_pHead = _pTail = pItem;
else {
// link new item onto tail of list using _pTail pointer
_pTail->_pNext = pItem; // links the current pTail to the new pItem
_pTail = pItem; // move the pTail to the new item
}
}
void Queue::removeItem() {
// check for empty queue
if (0 == _pHead)
{ // if empty, nothing to do
}
else
{
// pop top item off
QueueItem* popped = _pHead; // create popped to hold value of _pHead
_pHead = popped->_pNext; // Move the pHead to the next in queue
delete popped; // delete the popped value
--_itemCounter; // decrement counter
}
}
队列项.h
#pragma once
#include "Queue.h"
class QueueItem {
public:
QueueItem(const char* pData, int id); // ctor
void setNext(QueueItem* pItem);
QueueItem* getNext() const;
int getId() const;
const char* getData() const;
private:
char _data[30]; // data value (null terminated character string)
const int _itemId; // unique id for item in queue
QueueItem* _pNext; // next item in queue
};
在下面的 QueueItem.cpp 中,ctor 不正确。出现错误C++ 没有重载函数实例与指定类型匹配,我不知道为什么。看起来调用与定义匹配?
队列项.cpp
#include "QueueItem.h"
#include <cstring>
#include <string>
QueueItem::QueueItem(char* pData, int id) // ctor
: _itemId{ id } // Initialization list
{
strcpy_s(_data, pData);
_pNext = NULL;
}
void QueueItem::setNext(QueueItem* pItem)
{
_pNext = pItem;
}
QueueItem* QueueItem::getNext() const
{
return _pNext;
}
int QueueItem::getId() const
{
return _itemId;
}
const char* QueueItem::getData() const
{
return _data;
}
主文件
#include <iostream>
#include <conio.h>
#include "Queue.h"
using namespace std;
// note - you may need to change the definition of the main function to
// be consistent with what your C++ compiler expects.
int main() {
char anykey;
Queue myQueue;
myQueue.removeItem();
myQueue.addItem("red");
myQueue.addItem("green");
myQueue.addItem("blue");
myQueue.addItem("orange");
myQueue.print(); // print contents of queue (item ID and data)
myQueue.removeItem();
myQueue.removeItem();
myQueue.removeItem();
myQueue.removeItem();
myQueue.print();
myQueue.erase();
myQueue.addItem("olive");
myQueue.addItem("mauve");
myQueue.addItem("purple");
myQueue.print();
myQueue.erase();
myQueue.print();
cout << "Press any key...";
anykey = getch();
return 0;
}
解决方案
让我们按顺序来看看。
队列.h
#pragma once #include "QueueItem.h"
您实际上并没有使用
QueueItem
此标头中的定义,您只提到了指向它的指针。要拥有一个指向类型的指针(无需取消引用它——即在标头中)——我们只需要知道该类型是否存在。因此,您可以将包含替换为前向声明
class QueueItem;
并打破两个头文件之间的循环。(您现在需要包含在内
QueueItem.h
,Queue.cpp
因为您确实在那里使用它)。您实际上不需要包含
Queue.h
其中QueueItem.h
任何一个,因为它根本没有被使用。-
在下面的 Queue.cpp 中,有两个地方我认为代码应该是
_pTail->_pNext
或_pTail._pNext
.是的,你的第一个想法是正确的。
如果是->,那么我得到
C++ member (declared at line 21 of) is inaccessible
“无法访问”这个词告诉我们,问题
_pTail->_pNext
在于QueueItem::_pNext
声明private
。只有QueueItem
类(或朋友)本身的方法才被允许访问其private
成员。您可以添加一个
friend
声明以QueueItem
允许Queue
对其私有部分具有特权访问权限。但是,由于您已经有一个public
访问器,您可以_pTail->getNext()
改为编写。但使用 .
gives C++ expression must have class type
.这是因为只有类(以及结构和联合)对象才有成员。你有一个指向类对象的指针,所以
->
是正确的选择。如果它有助于记住,p->member
本质上与(*p).member
...相同,只是打字更好。 -
在
QueueItem.cpp
下面,ctor 是不正确的。出现错误 C++no instance of overloaded function matches the specified type
,我不知道为什么。看起来调用与定义匹配?这两个不一样:
QueueItem(const char* pData, int id); QueueItem::QueueItem( char* pData, int id) { ... }
我尝试尽可能地复制和粘贴这样的行 - 进行更多的打字没有任何好处,有更多的错误机会,当你知道你打算写什么时,有时很难看到这些简单的错误。
推荐阅读
- javascript - 使用 Postgraphile 进行关系查询
- azure - 从带有模式的目录中获取最新文件
- python-3.x - UnicodeDecodeError with 0xc3 in Python subprocess stdout in macOS
- vba - 需要代码来使用具有可变行范围的自动过滤器
- maven - 如何在一个地方为许多 gradle 项目声明依赖版本
- c++ - 返回一个数组,其中包含数组中小于或等于给定数组中元素的元素数
- kubernetes - 如何在微服务中实现 ECDH
- angular - 如何使用 Angular Mat-Sort-Table 通过 SHIFT 实现多项选择?
- node.js - 在变量中处理 RSA 密钥 Node.JS
- android - 如何在 Flutter 中实现音频流应用和安全存储