为什么使用new创建的对象范围有限?
Why is the scope of object created using new limited?
使用 new
运算符创建的对象在范围外似乎不可用!这不是 new
运算符的全部意义吗?
https://ideone.com/DDvo9y - 请检查此 link 以查看结果。
#include<iostream>
class myClass
{
private:
int val;
public:
myClass () = delete;
myClass (int val):val{val}{}
int get () const
{
return val;
}
};
bool ifEqualMake (int a, int b, myClass * obj)
{
if (a == b) obj = new myClass (a);
else{
std::cout << "Difference exists: " << a - b << '\n';
obj = new myClass (a + b);
}
std::cout << " Object made with value :" << obj->get () << '\n';
return (a == b);
}
int main ()
{
myClass *obj1 = nullptr;
myClass *obj2 = nullptr;
myClass *obj3 = nullptr;
ifEqualMake (3, 3, obj1);
ifEqualMake (4, 3, obj2);
ifEqualMake (4, 4, obj3);
if(obj1) std::cout << "obj 1 made in heap: " << obj1->get () << '\n';
if(obj2) std::cout << "obj 2 made in heap: " << obj2->get()<<'\n';
if(obj3) std::cout << "obj 3 made in heap: " << obj3->get () << '\n';
delete obj1;
delete obj2;
delete obj3;
return 0;
}
参数obj
是按值传递的,这意味着它只是参数的一个副本,函数内部对其自身的任何修改(如obj = new myClass (a);
)与原始参数无关指针。同时,函数内部构造的对象不会被销毁。
您可以将其更改为按引用传递。
bool
ifEqualMake (int a, int b, myClass *& obj)
// ^
{
...
}
不是。
您将使用 new
创建的动态分配对象与指向它的 指针 混淆了。
指针的范围与任何其他自动存储持续时间对象一样受到限制。
您似乎打算将它用作函数 ifEqualMake
的 "out" 参数,也许是通过引用它而不是复制它。然后对其进行更改,例如将其指向 new
对象,将反映在调用范围中。
考虑以下函数:
void foo(int i) {
i = 4;
}
void bar() {
int j = 0;
foo(j);
std::cout << j << '\n';
}
您希望 bar
打印 0
,而不是 4
,因为 foo
正在分配给局部变量。
此行为不会随指针改变。以下代码的行为方式相同:
void foo(int* i) {
int temp = 0;
i = &temp;
}
void bar() {
int* j = nullptr;
foo(j);
std::cout << j << '\n';
}
对您提供的代码最简单的修复是通过引用获取指针:
void foo(int*& i) {
int temp = 0;
i = &temp;
}
void bar() {
int* j = nullptr;
foo(j);
// j now points to a destroyed object
std::cout << j << '\n';
}
使用 new
运算符创建的对象在范围外似乎不可用!这不是 new
运算符的全部意义吗?
https://ideone.com/DDvo9y - 请检查此 link 以查看结果。
#include<iostream>
class myClass
{
private:
int val;
public:
myClass () = delete;
myClass (int val):val{val}{}
int get () const
{
return val;
}
};
bool ifEqualMake (int a, int b, myClass * obj)
{
if (a == b) obj = new myClass (a);
else{
std::cout << "Difference exists: " << a - b << '\n';
obj = new myClass (a + b);
}
std::cout << " Object made with value :" << obj->get () << '\n';
return (a == b);
}
int main ()
{
myClass *obj1 = nullptr;
myClass *obj2 = nullptr;
myClass *obj3 = nullptr;
ifEqualMake (3, 3, obj1);
ifEqualMake (4, 3, obj2);
ifEqualMake (4, 4, obj3);
if(obj1) std::cout << "obj 1 made in heap: " << obj1->get () << '\n';
if(obj2) std::cout << "obj 2 made in heap: " << obj2->get()<<'\n';
if(obj3) std::cout << "obj 3 made in heap: " << obj3->get () << '\n';
delete obj1;
delete obj2;
delete obj3;
return 0;
}
参数obj
是按值传递的,这意味着它只是参数的一个副本,函数内部对其自身的任何修改(如obj = new myClass (a);
)与原始参数无关指针。同时,函数内部构造的对象不会被销毁。
您可以将其更改为按引用传递。
bool
ifEqualMake (int a, int b, myClass *& obj)
// ^
{
...
}
不是。
您将使用 new
创建的动态分配对象与指向它的 指针 混淆了。
指针的范围与任何其他自动存储持续时间对象一样受到限制。
您似乎打算将它用作函数 ifEqualMake
的 "out" 参数,也许是通过引用它而不是复制它。然后对其进行更改,例如将其指向 new
对象,将反映在调用范围中。
考虑以下函数:
void foo(int i) {
i = 4;
}
void bar() {
int j = 0;
foo(j);
std::cout << j << '\n';
}
您希望 bar
打印 0
,而不是 4
,因为 foo
正在分配给局部变量。
此行为不会随指针改变。以下代码的行为方式相同:
void foo(int* i) {
int temp = 0;
i = &temp;
}
void bar() {
int* j = nullptr;
foo(j);
std::cout << j << '\n';
}
对您提供的代码最简单的修复是通过引用获取指针:
void foo(int*& i) {
int temp = 0;
i = &temp;
}
void bar() {
int* j = nullptr;
foo(j);
// j now points to a destroyed object
std::cout << j << '\n';
}