我写了一段简单的C ++代码来通过引用传递地址。
我将一个变量(比如说y)和一个数组(比如说arr)的地址传递给一个类。 arr 和 y 都将在类中修改。我想在main()中修改值。
请在下面的代码中找到我的问题,因为这样更容易。感谢。
#include <iostream>
using namespace std;
class A
{
public:
// Assign values to the array and increment _x.
void increment()
{
(*_x)++;
(*_arr)[0] = 1; // Q1. Is it safe to directly access the array like this.
(*_arr)[1] = 2; // Don't I have to allocate memory to the array ?
(*_arr)[2] = 3;
}
// Get the address of the Variable that is passed in main. x will now have &y2.
A (int* &arr, int* &x):
_x(x)
{
*_arr = arr;
}
private:
int* _x;
int** _arr;
};
int main()
{
int y = 9;
int arr[5];
int *pY = &y;
int *pArr = arr;
A *obj1 = new A(pArr, pY);
// This gives a compile time error. warning: initialization of non-const reference int *&' from rvalue `int *'
// A *obj1 = new A(&y); <-- Q2. Why does this give a Compile Time Error ?
obj1->increment();
cout << "y : " << y << endl;
cout << "[0]: " << arr[0] << "; [1]: " << arr[1] << "; [2]: " << arr[2] << endl;
cout << endl;
return 0;
}
提前致谢。
答案 0 :(得分:4)
问题1
在A :: increment()函数中,我直接将值赋给数组而不分配内存。这样做安全吗?如果没有,我如何分配内存,以便仍然可以在main()?
中获取修改后的数组值
<强>答案强>
是的,这是安全的。
问题2
为什么在我传递给A&#; s构造函数时会出现编译时错误?
<强>答案强>
<div>
<label>Enter a different Value: </label><input id="txtOne" />
<input type="button" id="btnOne" value="Set Data" onclick="btn1Click(this);" />
</div>
<script type="text/javascript">
var btn1 = document.getElementById('btnOne');
var input1 = document.getElementById('txtOne');
function btn1Click(e)
{
localStorage.dataItem = input1.value;
}
</script>
不是左值。因此,在参数类型为&y
的情况下不能使用它。
发布代码中的问题
int*&
这是一个问题,因为 *_arr = arr;
尚未初始化为指向有效内存。在_arr
尚未初始化时使用*_arr
会导致未定义的行为。您可以将_arr
的类型更改为:
_arr
并简化您的代码。
int* _arr;
不改变class A
{
public:
// Assign values to the array and increment _x.
void increment()
{
(*_x)++;
_arr[0] = 1; // Q1. Is it safe to directly access the array like this.
_arr[1] = 2; // Don't I have to allocate memory to the array ?
_arr[2] = 3;
}
// Get the address of the Variable that is passed in main. x will now have &y2.
A (int* &arr, int* &x):
_x(x),
_arr(arr)
{
}
private:
int* _x;
int* _arr;
};
中的任何内容。
答案 1 :(得分:1)
这很少是你想要的; T**
通常是一个数组数组,或者是您想要在调用者范围内修改的指针值。但是,这似乎都不是你在这里做的。
当且仅当*_arr[0]
已初始化为非const数组数组时才可以修改_arr
,(*_arr)[0]
当且仅当它已初始化为非{指向非const数组的指针。这里似乎都不是这种情况,但如果是这样的话,你可能想要明确地给出数组长度。
在此示例中,&y
是常量。您无法修改它,因此您不能将其作为非const变量传递。您可以声明指针int *py = &y;
并传递它。但请考虑这是否是你想要做的。
顺便说一下,使用以下划线开头的标识符并不好,因为按照标准,它们是为编译器保留使用的。
答案 2 :(得分:1)
你应该告诉我们你要做什么。在我看来,没有充分理由,在C ++中使用原始指针/数组和裸新/(缺少?)删除是无意义的。我还要注意,对于类成员使用_prefix不是一种好的做法。通常,前导_用于std实现。如果你坚持使用m_prefix,我建议你使用它。为什么你给_arr类型int **?是应该是2D阵列?另外,通过引用传递指针确实没有意义。指针已经是一个指针,如果你知道我的意思,只需传递指针。
我只是假设你这样做是为了理解手动内存管理或指针算术或者 - 等等,对:告诉我们你要做什么以及为什么。然而,我不明白你的课程是什么:
#include <iostream>
void increment(int& x, int *arr, int sz)
{
++x;
for (int i = 0; i != sz; ++i)
{
// this just numbers the values respectively (starting at 1)
arr[i] = i + 1;
}
}
int main()
{
using namespace std;
int y = 9;
const int sz = 5;
int arr[sz];
increment(y, arr, sz);
cout << "y : " << y << '\n'
<< "[0]: " << arr[0] << "; [1]: " << arr[1] << "; [2]: " << arr[2] << "\n\n";
}
回答你的问题: 2.首先要做的是:我没有看到任何只需要一个参数的构造函数。
我不能重复,以至于我不明白你的目标是什么,这使得很难给出可靠的建议。
我试着修复你的版本..它仍然很可怕......我强烈建议你阅读std :: array,std :: vector。也许在指针,C风格的数组以及如何将C风格的数组作为函数参数传递(注意:对于常规的C ++编程,你通常不会这样做/使用它。)
#include <iostream>
class A {
public:
// Assign values to the array and increment m_x.
void increment()
{
++(*m_x);
m_arr[0] = 1;
m_arr[1] = 2;
m_arr[2] = 3;
}
A (int* arr, int* x):
m_x(x), m_arr(arr)
{
}
private:
int* m_x;
int* m_arr;
};
int main()
{
using namespace std;
int y = 9;
int arr[5];
A obj1(arr, &y);
obj1.increment();
cout << "y : " << y << '\n'
<< "[0]: " << arr[0] << "; [1]: " << arr[1] << "; [2]: " << arr[2] << "\n\n";
A obj2(arr, &y);
obj2.increment();
cout << "y : " << y << '\n'
<< "[0]: " << arr[0] << "; [1]: " << arr[1] << "; [2]: " << arr[2] << "\n\n";
}
你还应该读取非指针/引用及其差异
我实际上是想让您的编程生活更轻松。对不起,答案很长。
答案 3 :(得分:0)
回答你的第一个问题
在A :: increment()函数中,我直接为其赋值 数组没有分配内存。这样做安全吗?如果没有,我该怎么办 分配内存,以便我仍然可以获取修改后的数组值 main()?
你在main()中的行
中分配了内存int arr[5];
在类设计方面,您定义了类构造函数以接受引用参数,这意味着必须将现有的int *传递给每个参数:
A (int* &arr, int* &x)
并在调用构造函数时执行此操作:
A *obj1 = new A(pArr, pY);
所以在这个程序中,你正在做的是安全的。如果你希望在另一个上下文中使用这个类,那么潜在的危险就是你的main()中的arr数组包含少于3个元素,因为你的increment()函数初始化了数组的第三个元素。
回答你的第二个问题
为什么在我传递给A&#; s构造函数时会出现编译时错误?
在原始构造函数中,
// Get the address of the Variable that is passed in main. x will now have &y2.
A (int* &arr, int* &x):
_x(x)
{
*_arr = arr;
}
您在初始化之前解除引用_arr
。解决这个问题的一种方法是:
// Get the address of the Variable that is passed in main. x will now have &y2.
A (int* &arr, int* &x):
_x(x)
{
_arr = new (int*);
*_arr = arr;
}
// Destructor
~A ()
{
delete _arr;
}
另外,您还可以在main()中使用new
。每当您使用new
时,您还应该使用delete
来避免内存泄漏。因此,在程序的底部,在return
语句之前,添加以下内容:
delete obj1;