列表类,其中填充了返回时丢失地址的指针
List Class filled with pointers losing adresses on return
我有一个名为DiGraph的类,它包含一个指向节点指针的数组:
DiGraph::DiGraph(int Size) : count(0){
nodes = new Node *[Size];
}
现在我想定义函数getNodes(),它本质上应该以列表形式返回数组:
Liste<Node*> DiGraph::getNodes() {
Liste<Node*> nlist(count+1);
for (int i = 0; i < count; i++) {
nlist.append(nodes[i]);
}
return nlist;
}
在函数结束时,nlist被正确填充,但不知何故,函数调用处的结果副本不包含正确的指针,而是包含所有其他变量。
DiGraph a(6);
a.addNode(new Node("A", 50, 50));
Liste<Node*> gN = a.getNodes(); //gN does not contain the same pointers that were returned
类"Liste"基本上是一个带有模板和一些奇特函数的动态数组。
现在我认为答案可能是nlist在函数结束后被销毁,但指针在nodes变量中仍然有效,那么为什么副本中包含无效的指针呢?
编辑
这是列表类:
#ifndef _LISTE_H
#define _LISTE_H
// -------------------------------------------------------------------
template <typename T>
class Liste {
private:
T *_values;
int _last;
int _size;
bool isFull();
int find(T value);
void increase();
void decrease();
public:
Liste(int size = 8);
Liste(Liste &list);
~Liste();
void append(T value);
void remove(T value);
T getValueAt(int pos);
int size();
T operator[](int pos);
};
// -------------------------------------------------------------------
template <typename T>
Liste<T>::Liste(int size) {
_size = size;
_last = 0;
_values = new T[size];
}
template <typename T>
Liste<T>::Liste(Liste &list) {
_size = list._size;
_last = list._last;
_values = list._values;
}
// -------------------------------------------------------------------
template <typename T>
Liste<T>::~Liste() {
delete[] _values;
}
// -------------------------------------------------------------------
template <typename T>
void Liste<T>::increase() {
T *tmp = new T[_size * 2];
for (int i = 0; i < _size; i++)
tmp[i] = _values[i];
delete[] _values;
_values = tmp;
_size *= 2;
}
// -------------------------------------------------------------------
template <typename T>
void Liste<T>::decrease() {
_size /= 2;
T *tmp = new T[_size];
for (int i = 0; i < _size; i++)
tmp[i] = _values[i];
delete[] _values;
_values = tmp;
}
// -------------------------------------------------------------------
template <typename T>
bool Liste<T>::isFull() {
return _last == _size;
}
// -------------------------------------------------------------------
template <typename T>
int Liste<T>::find(T val) {
int pos;
for (pos = 0; pos < _last; pos++)
if (_values[pos] == val)
return pos;
return -1;
}
// -------------------------------------------------------------------
template <typename T>
T Liste<T>::getValueAt(int pos) {
if (pos < 0 || pos >= _last)
throw "OutOfBoundsException";
return _values[pos];
}
// -------------------------------------------------------------------
template <typename T>
void Liste<T>::append(T val) {
if (isFull())
increase();
_values[_last] = val;
_last += 1;
}
// -------------------------------------------------------------------
template <typename T>
void Liste<T>::remove(T val) {
int pos = find(val);
if (pos == -1)
throw "ValueNotFoundException";
for (; pos < _last - 1; pos++)
_values[pos] = _values[pos + 1];
_last -= 1;
if (_last < _size / 4)
decrease();
}
// -------------------------------------------------------------------
template <typename T>
int Liste<T>::size() {
return _last;
}
// -------------------------------------------------------------------
template <typename T>
T Liste<T>::operator[](int pos) {
return getValueAt(pos);
}
#endif
template <typename T>
Liste<T>::Liste(Liste &list) {
_size = list._size;
_last = list._last;
_values = list._values;
}
此代码的作用是使新的Liste对象(由复制构造函数构造)指向现有Liste对象的内存地址。但是这个对象会被破坏,所以你会得到一个悬空的指针。您需要执行值的硬拷贝。
template <typename T>
Liste<T>::Liste(const Liste &list) { // <--- const
_size = list._size;
_last = list._last;
_values = new T[_size];
for( std::size_t iter = 0 ; iter < _size ; ++iter )
{
_values[iter] = list._values[iter];
}
}
将指针成员包装到智能指针(例如unique_ptr<>
)是一种很好的现代实践。通过这种方式,您永远不会忘记删除所有内容,并且即使在构造函数不完整(抛出异常)的情况下,也可以保证清理对象保留。
如果你计划按价值回报,你应该研究如何让你的李斯特类移动感知
您的T operator[](int pos);
也可以通过引用返回包含的项,以允许立即修改对象(T& operator[](int pos);
),因为它返回位于_values[pos]
的对象的副本,很可能不是您想要的。与T getValueAt(int pos);
公共方法类似。
相关文章:
- C++ 指针的内存地址和指向数组的内存地址如何相同?
- 在C++中打印指向不同基元数据类型的指针的内存地址
- 将地址分配给本地指针后,公共对象的变量将消失
- 为什么指针不写入类的地址?
- CUDA:统一内存和指针地址的更改
- 为什么 vector 的随机访问迭代器给出与指针不同的内存地址?
- 如何从绝对地址的 C 样式指针创建对C++对象的引用
- 当我在 C++ 中将派生类的指针分配给指针时,地址会更改
- 是否可以仅通过将分配的指针地址存储在C++中来分析内存?
- 如何在程序集函数中将元素数组作为参数传递时转发 ARM 寄存器的地址指针
- 如何使用构造函数初始化内存地址(指针变量)?
- 数组基础地址指针
- 如何在不使用返回的情况下从函数获取变量的地址(指针)
- 保存QWidgets的地址/指针
- C++ 读取内存地址/指针和偏移量
- 从存储在 CTreeCtrl 的 LPARAM 中的结构中检索地址/指针 (IXMLDOMNode*) - 不起作用
- 简单的C++地址/指针澄清
- 如何获取成员函数的地址指针
- 当“按引用传递”成为强制传递而不是按地址/指针传递时
- C++ 为什么不是同一个地址(指针)