在其他范围内为指针创建实例

时间:2011-01-07 10:05:28

标签: c++ pointers

我有两种方法为指针创建实例。 但其中一个会失败。

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错了?

3 个答案:

答案 0 :(得分:6)

语法有效,但由于testPointer1()正在指针的副本上运行,而不是实际指针本身,因此它无法执行您想要的操作。因此,当您将地址分配给新分配的对象时,它将被分配给副本,而不是原始的a1指针。

因此,地址丢失并导致内存泄漏。此外,由于原始的a1指针从未被修改过,所以您试图取消引用空指针,这是一件坏事。

我会说testPointer2()是更好的方法,但是如果你想让testPointer1()工作,试试这个:

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

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


额外说明:

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

另请注意,完成后必须手动delete所有new个ed对象,否则会出现泄漏。通常,您可以将指针包装在自己的类中并实现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));
} 

答案 1 :(得分:2)

testPointer1函数适用于所提供指针的副本a中对testPointer1的修改不会反映给调用者。

这与这个更简单的例子完全相同:

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

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

如果您希望将testInt1中的更改反映给调用者,则必须传递指针或对i的引用(而不仅仅是 i)。相同的解决方案可以应用于您的特定情况,但有人可能会争辩指针指针和指针引用并不是最佳实践。

答案 2 :(得分:-1)

这是家庭作业吗?

这似乎是显而易见的: 形式参数保存在堆栈和&amp;方法/函数调用后恢复。

然后无论f(x型),在函数/方法中操纵x都不会改变函数外的值。

即使type是指针类型。

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

在你的情况下: A * a1 = NULL 调用您的方法不会更改testPointer1之外的a1的值 所以a1在通话后仍然是NULL。