[英]Class member suddenly becomes inaccessible/non-existent
我主要是在循环中调用一个函数( func1
)。 该函数是Class1
的成员。 我正在将不同类Class2
的对象( object2
)传递给此函数。 在循环的第一次迭代中,可以从main访问变量var2
( Class2
成员),但是在第二次迭代中则不能。 我收到“访问冲突读取位置”错误。 这是我的代码:
main.cpp:
#include "Class1.h"
int main(){
Class2 object2;
object2.assign_var2();
Class1 object1;
for (int i = 0; i < 2; ++i){
std::cout << object2.var[0][0][0] << std::endl; // Works ONLY on first iteration
object1.func1(object2)
}
}
Class2.h:
class Class2{
... other variables and functions declared
public:
Class2::Class2();
Class2::~Class2();
double *** var2;
void assign_var2();
}
Class2.cpp:
Class2::Class2(){
var2 = new double**[200];
for (int i = 0; i < 200; ++i) {
var2[i] = new double*[200];
for (int j = 0; j < 200; ++j){
var2[i][j] = new double[2];
}
}
Class2::~Class2(){
for (int i = 0; i < 200; ++i){
for (int j = 0; j < 200; ++j){
delete [] var2[i][j];
}
delete [] var2[i];
}
delete [] var2;
}
void assign_var2(){
for (int i = 0; i<200; ++i){
for (int j = 0; j<200; ++j){
var2[i][j][0] = some_number1;
var2[i][j][1] = some_number2;
}
}
}
}
Class1.h:
#include "Class2.h"
class Class1{
... other variables, functions declared
public:
void func1(Class2)
}
Class1.cpp:
Class1::func1(Class2 object2){
int u = object2.var2[1][2][0];
int v = object2.var2[1][2][1];
}
旁注:如果我尝试打印一个不同的变量而不是var2
,那么它似乎可以在第二次迭代中使用,因此我认为对象本身没有问题。
提前致谢!!
问题是Class1::func1(Class2 object2)
按值接受参数。 这意味着将创建Class2
对象的副本,然后在func1()
返回时销毁该副本。
在Class2
类中,您没有定义复制构造函数,因此编译器将为您创建一个仅按成员复制成员的值。 然后,当副本的析构函数运行时,它将delete
所有分配,使原始对象具有指向无效对象的指针。 这就是为什么它在第二次迭代中失败。
始终遵循三个规则 :如果需要自定义析构函数,复制构造函数或复制赋值运算符,则需要全部三个 。 适当的复制构造函数将为所有数组创建新分配,并将数据复制到它们。 (如果您使用的是C ++ 11,那么实际上这是五个规则 :您可能还希望实现move构造函数和move赋值运算符,以便在知道对象已被赋值的情况下“窃取” var2
指针。是右值,因此无论如何很快就会消失。)
就您而言,解决方法很简单:按值接受参数:
Class1::func1(Class2 const & object2)
我强烈建议为您的var2
成员改用std::vector<std::vector<std::vector<double>>>
,因为那样编译器生成的析构函数,复制构造函数和复制赋值运算符都可以正确的事情,您将不需要实施其中任何一个。
这与使func1()
接受引用func1()
:虽然发生错误是因为没有自定义副本构造函数,但我们实际上根本不想在这里创建副本,因为我们没有修改数据。 仅为了破坏副本而复制数据是愚蠢的。 让我们只接受对现有对象的引用,而不需要多余的副本。
或者,您可以完全禁用复制:
class Class2 {
// ...
// For C++11: explicitly delete the copy-ctor and copy-assignment operator.
public:
Class2(Class2 const &) = delete;
Class2 & operator=(Class2 const &) = delete;
// For C++03: declare the copy-ctor and copy-assignment operator private and
// then do not implement them. (C++03 doesn't have the "= delete" syntax.)
private:
Class2(Class2 const &);
Class2 & operator=(Class2 const &);
如果禁用然后复制你会得到关于调用编译时错误object1.func1(object2)
因为它依赖于一个拷贝构造函数存在object2
。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.