2011-01-07 34 views
0

我有两种方法为指针创建实例。 但其中一人将失败。为其他作用域中的指针创建实例

class A { 
public: 
    int num; 
}; 

void testPointer1(A* a){ 
    a = new A(); 
    a->num = 10; 
} 
A* testPointer2(){ 
    A* a = new A(); 
    a->num = 10; 
    return a; 
} 
void testPointer() { 
    A* a1 = NULL; 
    testPointer1(a1); // this one fails 
    //cout << a1->num << endl; // segmentation fault 

    A* a2 = NULL; 
    a2 = testPointer2(); 
    cout << a2->num << endl; 
} 

为什么testPointer1错了?

回答

6

语法是有效的,但它不会做你想要的,因为testPointer1()正在对指针的副本进行操作,而不是实际的指针本身。因此,当您将地址分配给新分配的对象时,它将被分配给副本,而不是指向原始的a1指针。

因为这个原因,地址丢失了,你得到了内存泄漏。另外,由于原来的a1指针从来没有被修改过,所以你试图取消引用空指针,这是一件坏事。

我想说testPointer2()是更好的方式来做到这一点,但如果你想testPointer1()工作,试试这个:“为指针,以A参考”

void testPointer1(A*& a) 
{ 
    a = new A(); 
    a->num = 10; 
} 

的参数类型指示这样,代替传递指针的副本,引用将被传递给原始指针。 C++引用是另一个对象的别名。所以无论你在别名上做什么,它都会在原始对象上执行。


附加说明:

注意,在new A();are actually significant and their presence or absence makes a difference括号。

另外请注意,您必须手动完成delete所有new编辑的对象,否则将发生泄漏。通常,您会将指针包装在自己的类中,并执行RAII或使用smart pointer(如Boost's smart pointersauto_ptr)来实现正确的内存管理和异常安全。

如果你打算在初始化时设置num的值,为什么不创建一个构造函数?

class A 
{ 
public: 
    A(int n) : num(n) {} 
    int GetNum() const { return num; } 
private: 
    int num; 
}; 

void testPointer1(A*& a) 
{ 
    a = new A(10); 
} 

A* testPointer2() 
{ 
    return new A(10); 
} 

// auto_ptr example, see link in second note above 
std::auto_ptr<A> testPointer3() 
{ 
    return auto_ptr<A>(new A(10)); 
} 
2

testPointer1功能工作所提供的指针的一个拷贝:修改在testPointer1a没有反映给调用者。

这正是像这样简单的例子:

void testInt1(int i) 
{ 
    i++; 
} 

void testInt() 
{ 
    int i = 0; 
    testInt1(i); 
    // i is still 0 
} 

如果你想在testInt1的变化反映到主叫方,则必须通过其中一个指针或引用i(而不仅仅是i)。同样的解决方案可以应用于您的具体情况,但有人可能会争辩说,指向指针的指针和对指针的引用并不是最佳实践。

+0

+1:我喜欢你分解它的方式来说明确切的问题 - 酷! – 2011-01-07 11:15:04

-1

这是功课吗?

这似乎很明显: 形式参数保存在栈上&在方法/函数调用后恢复。然后,无论f(类型x),在函数/方法内部操作x都不会改变函数外部的值。

即使类型是指针类型。

在函数内进行x更改的唯一方法是通过引用或指向类型的指针来告诉它是可修改的。

你的情况: A * A1 = NULL 调用你的方法不会改变testPointer1 所以A1的A1之外的价值仍然会在调用之后NULL。

相关问题