c++ - 为什么嵌套类对外部类不可见
问题描述
我对嵌套类的问题感到困惑
#ifndef MINIGRAPH_H_
#define MINIGRAPH_H_
#include<vector>
#include<list>
#include<iostream>
template <typename VEX,typename EDGE>
class MiniGraph
{
public:
class _Node
{
public:
VEX _Vex;
EDGE _Edge;
_Node* next;
};
MiniGraph() {};
MiniGraph(int vex_num);
void add(VEX from, VEX to, EDGE Edge);
//void display();
private:
std::vector<void*> _VecNode;
_Node* NewNode(VEX vex) { _Node* ptr = new _Node;ptr->_Vex = vex;return ptr; }
_Node* NewNode(VEX vex, EDGE edge) { _Node* ptr = new _Node;ptr->_Vex = vex;ptr->_Edge = edge;return ptr; }
};
template <typename VEX, typename EDGE>
MiniGraph<VEX, EDGE>::MiniGraph(int vex_num)
{
int i = 0;
for (i = 0;i < vex_num;i++)
{
struct Node *ptr_tmp = new _Node;
ptr_tmp->next = NULL;
_VecNode.push_back(ptr_tmp);
}
}
template <typename VEX, typename EDGE>
void MiniGraph<VEX, EDGE>::add(VEX from, VEX to, EDGE edge)
{
int i;
_Node* ptr_node = NULL;
for (i = 1;i < _VecNode.size();i++)
{
ptr_node = (_Node*)_VecNode[i];
if (ptr_node->_Vex == from)
break;
}
if (i == _VecNode.size())
{
ptr_node = NewNode(from);
_VecNode.push_back(ptr_node);
}
ptr_node = NewNode(from, edge);
**ptr_node->next = (_Node*)_VecNode[i]->next;//insert node from head**
_VecNode[i]->next = ptr_node;
}
编译时
#include "MiniGraph.h"
void main()
{
MiniGraph<int, double> hh;
hh.add(1, 2, 0.1);
hh.add(1, 3, 0.2);
hh.add(2, 3, 0.3);
}
ptr_node->next = (_Node*)_VecNode[i]->next;//insert node from head
说 -> 左下角必须指向类/结构/联合/通用类型时触发的错误;但是_Node被声明了。我试图用结构替换类,但它触发了同样的错误。似乎声明不可见。我应该如何解决这个问题?
解决方案
正如上面评论中提到的@WhozCraig,您有一个 的向量void*
,而不是 的向量Node*
。因此没有被调用的成员next
。您可以将 type_cast 转换void*
为 aNode*
来“修复”问题,但您会大吃一惊。
问题从你的main
功能开始。
int main()
{
MiniGraph<int, double> hh;
此代码将调用该类的默认构造函数MiniGraph
。这意味着 noNodes
将被创建,并且您的向量 ofNode*
将为空(即std::vector<Node*>::size = 0
.
然后调用add
函数:
hh.add(1, 2, 0.1);
在add
函数内部会发生以下情况:
void add(VEX from_, VEX to_, EDGE edge_)
{
std::size_t i = 0;
for (i=1; i<node_ptrs.size(); i++)
{
if (node_ptrs[i]->vex == from_)
break;
}
在第一次调用之后add()
,向量size = 0
,但是i = 1
。那是因为您i=1
在 for 循环中进行了初始化。
然后检查是否i == vector::size
.
Node *tmp = nullptr;
if (i == node_ptrs.size())
{
tmp = NewNode(from_);
node_ptrs.push_back(tmp);
}
上面的 if 语句永远不会被执行,因为i = 1
和vector::size = 0
.
最后,您执行以下操作:
tmp = NewNode(from_, edge_);
tmp->next = node_ptrs[i]->next; // this fails because your vector size is 0!
node_ptrs[i]->next = tmp;
第一行有效。tmp
是一个Node*
指向新创建的Node
. 好的。然后程序因分段错误而失败,因为tmp->next
它试图浅拷贝i
向量元素中的指针。现在请记住,i = 1
向量仍然是空的,即vector::size = 0
。没有node_ptrs[1]
可复制的元素。这就是它崩溃的原因。
上述代码示例:https ://rextester.com/DTODK86272
在您的原始代码中还有更多问题需要考虑......例如:
- 如果只有一个指针指向某个
Node
,则使用unique_ptr
. 您仍然可以从 a 读取其他指针unique_ptr
,但他们将无法做任何其他事情。 - 编写初始化指针的构造函数,并在and成员
nullptr
上调用零初始化。vex
edge
- 避免
int
用作数组索引。如果有人决定使用负数作为函数参数怎么办? - 在您的实现中,您必须在开始执行任何其他操作之前检查向量是否为空。如果向量为空,会发生什么?
推荐阅读
- django - 如何在 Django 视图类中设置缓存控制标头(无缓存)
- python - 熊猫数据框上的高效矢量化替换
- azure-iot-central - 在 azure IoT Central 中哪里可以找到设备的模块名称
- export - 如何出口所有产品?
- python - 添加一天到日期列 - dateadd 或 timedelta
- php - 在方法内部调用setter方法
- google-fit-api - Google Fit REST API 移动分钟数
- r - 在矩阵中使用 vctrs
- c - 将 ppm 图像转换为灰度图像
- python - 有没有办法打包python代码,这样其他机器就不需要使用pip安装所有依赖项了