类成员突然变得不可访问/不存在
Class member suddenly becomes inaccessible/non-existent
在我的main中,我在循环中调用一个函数(func1
(。此函数是 Class1
的成员。我正在传递一个不同类的对象(object2
(,Class2
到这个函数。在循环的第一次迭代中,变量 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)
}
}
类2.h:
class Class2{
... other variables and functions declared
public:
Class2::Class2();
Class2::~Class2();
double *** var2;
void assign_var2();
}
2类.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;
}
}
}
}
1.h类:
#include "Class2.h"
class Class1{
... other variables, functions declared
public:
void func1(Class2)
}
类1.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,那么它实际上是五法则:您可能还希望实现移动构造函数和移动赋值运算符,以便在您知道被分配的对象是右值的情况下可以"窃取"var2
指针,因此无论如何都会很快消失。
在您的情况下,修复很简单:按值接受参数:
Class1::func1(Class2 const & object2)
我强烈建议改用std::vector<std::vector<std::vector<double>>>
作为var2
成员,因为这样编译器生成的析构函数、复制构造函数和复制赋值运算符都将执行正确的操作,并且您不需要实现它们中的任何一个。
这与使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
的复制构造函数。
- 我们可以访问一个不存在的联盟的成员吗
- C++:对不存在的命名空间使用命名空间指令
- g++ 说函数不存在,即使包含正确的标头
- 显式 std::exception_ptr 转换为 bool 不存在.VS2010 错误?
- C++ 尝试在不存在的构造函数中引用已删除的函数(使用 rapidJson)
- 查找第一个数组中不存在的元素
- 查找不存在的键时,unordered_map返回什么
- 如何优化代码以返回最接近给定整数的数字,但给定列表中不存在?
- set::find 查找不存在的元素
- 有没有办法将字符串添加到 Vector 中,但前提是它尚不存在?->C++
- inet_ntop返回不存在的地址
- CPP 使用不存在的键访问映射
- 如果键不存在,使用 [] 运算符访问 STL Map 元素会添加新元素
- 就SFINAE而言,访问不存在的成员不被视为"error"吗?
- 类成员突然变得不可访问/不存在
- 访问可能不存在的const vector成员- try/catch或if (count != 0)
- C++当"extern int * name"引用不存在的变量,然后访问"name"时会发生什么
- 如何在C++11中访问可能不存在的类型别名
- 实现一个 dinamic 数组(我可以访问不存在的位置)
- 访问内存中不存在的数组索引的正确异常类型?