我构建了一个类,该类存储缓冲区类型,缓冲区大小和指向该缓冲区的指针。
目的是通过该指针访问缓冲区以执行所有操作。
问题是,当我将此类的实例分配给另一个实例时,就这样:
buffer = ExampleUsage(10);
指针中断。
这是两个类(缓冲区和该缓冲区的用法):
首先,我在示例中使用的缓冲区:
class ExampleBuffer {
public:
ExampleBuffer() :size(0), buffer(0) {}
ExampleBuffer(size_t size) {
this->size = size;
buffer = vector<int>(size);
}
void Draw(int index, int val) {
buffer[index] = val;
}
int Get(int index) {
return buffer[index];
}
protected:
int size;
vector<int> buffer;
};
下一个我用来访问缓冲区并对其执行操作的类:
class ExampleUsage {
public:
ExampleUsage() :
size(0),
buffer(0),
ptr(&buffer) {}
ExampleUsage(int size) :
size(size),
buffer(size),
ptr(&buffer) {}
void Draw(int index, int val) {
ptr->Draw(index, val);
}
int Get(int index) {
return ptr->Get(index);
}
protected:
int size;
ExampleBuffer buffer;
ExampleBuffer* ptr;
};
这是一个演示该问题的程序。
class SomeClass {
public:
void Init() {
buffer = ExampleUsage(10);
}
void DoStuff() {
buffer.Draw(0, 1234);
}
protected:
ExampleUsage buffer;
};
int main() {
SomeClass example;
example.Init();
example.DoStuff();
}
执行时,将使用其默认构造函数初始化ExampleUsage
然后在Init()
的{{1}}方法中生成另一个实例,并将其分配给SomeClass
。
然后调用方法buffer
,该方法执行缓冲区的DoStuff()
方法,然后指针应从那里访问存储的Draw()
,但它指向nullptr而不是导致异常。>
我知道,如果我删除该行:
ExampleBuffer
,而是将其替换为:
buffer = ExampleUsage(10);
它将起作用。
为什么 buffer.Init(10); //hypothetical method to initialize the class.
中的指针未指向该程序中的ExampleUsage
?
答案 0 :(得分:2)
在此代码中,您将同时复制矢量和指针:
buffer = ExampleUsage(10);
一天结束时,缓冲对象具有向量的有效副本以及指向另一个向量最近所在的某个内存的指针。
class ExampleUsage {
// ...
ExampleBuffer buffer; // This is a valid copy of the object
ExampleBuffer* ptr; // Where does this ptr point after the copying?
};
这是出现异常的原因。 有关代码的其他问题: 如果您将此信息存储为vector :: size(),为什么还要在外部存储大小? 为什么同时存储矢量和指针(首选使用指针)?
考虑一个更简单的C ++惯用解决方案。