我难以用文字解释问题。但我在一个最小的例子中复制了我的问题。 基本上我有一个主类,持有不同类对象的向量。 这个主类有一个成员函数,它创建一个对象,将它添加到向量中,并返回一个指向向量中新对象的指针。 然后,当我尝试从返回的指针访问对象的值时,这些值就像从未设置过一样。
以下是最小示例的代码:
修改
有些人指出我在成员函数中有value = value。 这显然是一个错误,我已编辑为_value = value
#include <iostream>
#include <vector>
class MySecondaryClass
{
public:
MySecondaryClass(int aValue) { _aValue = aValue; }
~MySecondaryClass() {}
int _aValue;
};
class MyMainClass
{
private:
std::vector<MySecondaryClass> _secClassVec;
public:
MyMainClass() {}
~MyMainClass(){}
MySecondaryClass* addNewSecClass(int aValue) {
MySecondaryClass newSecClass(aValue);
_secClassVec.push_back(newSecClass);
return &_secClassVec[_secClassVec.size() - 1];
}
};
int main() {
MyMainClass mainObject;
MySecondaryClass* secObject1_ptr = mainObject.addNewSecClass(1);
MySecondaryClass* secObject2_ptr = mainObject.addNewSecClass(2);
MySecondaryClass* secObject3_ptr = mainObject.addNewSecClass(3);
std::cout << secObject1_ptr->_aValue << std::endl;
std::cout << secObject2_ptr->_aValue << std::endl;
std::cout << secObject3_ptr->_aValue << std::endl;
return 0;
}
输出:
-572662307
-572662307
3
预期输出为:
1
2
3
有人可以解释我在这里做错了吗?
答案 0 :(得分:1)
将构造函数参数命名为无法在构造函数体中隐藏您的成员,并开始使用initialzier列表:
MySecondaryClass(int aValue_) : aValue(aValue_)
{ }
还要记住,推回向量可能会使迭代器(以及指向其元素的指针)失效。
好吧,既然你编辑了你的问题。我只能建议你像指针一样返回表现的代理对象。
class MySecondaryClassPtr
{
MyMainClass& mmc_;
std::size_t pos_;
public:
MySecondaryClassPtr(MyMainClass& mmc, std::size_t pos) :
msc_(msc), pos_(pos)
{}
MySecondaryClass& operator*() { return mmc_._secClassVec[pos_]; }
MySecondaryClass* operator->() { return &mmc_._secClassVec[pos_]; }
};
这个&#34;智能指针&#34;代理对象与MyMainClass
对象的生命周期相关联,而不是向量的内部存储。
答案 1 :(得分:1)
第一个问题是在构造函数中:
import numpy as np
board=np.zeros((8,8))
board[0:,0]=1
它的作用是将参数aValue赋给自身,即不设置类的aValue属性。这可以通过以下任一方法解决:
MySecondaryClass(int aValue) { aValue = aValue; }
或
MySecondaryClass(int aValue) { this->aValue = aValue; }
但总的来说,这就是为什么不建议将参数命名为与属性相同的原因。
第二个问题是,呼叫:
MySecondaryClass(int aValue): aValue(aValue) {}
可能使分配给MySecondaryClass* secObject3_ptr = mainObject.addNewSecClass(3);
和secObject1_ptr
的内存无效(如果向量调整大小) - 基本上每次调用secObject2_ptr
都可能使先前返回的指针无效(从技术上讲,它是未定义的行为)。
修改强>
要回答评论问题:如果要将实际对象存储在类中并访问它们,则需要通过索引以不同方式执行,或者在某些情况下,您可以按ID保留映射,具体取决于你需要。但是你通常无法保持指向不断变化的数据结构的指针。
一种可能性:
mainObject.addNewSecClass()
但是,如果只添加到矢量,这也只能起作用。删除也会在删除项目后使索引无效。
另一种可能性是动态分配并仅将指针保留在向量中 - 然后在添加项目时原始对象地址不会改变。但随后需要管理生命周期,复制构造等,这可以通过使用智能指针(例如shared_ptr)进行一定程度的缓解。
答案 2 :(得分:0)
当你推入一个向量时,它必须为新元素分配内存。
此分配需求可能无法在内存中当前位于内存中的位置处满足,因此向量必须为其他内容的整个内容分配连续内存,移动旧内容,添加新内容并释放以前分配的块。
因此,每次更改矢量时,指向内存的指针都会变为无效。