指针的额外好处,何时使用,为什么使用 我现在正在学习C++,虽然我掌握了指针和引用的概念,但有些事情并不清楚。 假设我有以下代码(假设矩形有效,实际代码并不重要): #包括 #包括“矩形.h” 无效变更(矩形和rec); int main() { 矩形矩形; 矩形集合x(50); 矩形集y(75); std::cout

指针的额外好处,何时使用,为什么使用 我现在正在学习C++,虽然我掌握了指针和引用的概念,但有些事情并不清楚。 假设我有以下代码(假设矩形有效,实际代码并不重要): #包括 #包括“矩形.h” 无效变更(矩形和rec); int main() { 矩形矩形; 矩形集合x(50); 矩形集y(75); std::cout,c++,reference,pointers,oop,C++,Reference,Pointers,Oop,rectwo与rect的不同之处在于rect是堆栈上Rectangle的一个实例,而rectwo是堆上Rectangle的地址。如果按值传递Rectangle,则会生成它的一个副本,并且您将无法进行任何更改不在changestuff()的范围内 通过引用传递它意味着changestuff将具有矩形实例本身的内存地址,并且更改不限于changestuff的范围(因为矩形) 编辑:您的评论使问题更加清晰。一般来说,引用比指针更安全 来自维基百科: 在引用对象创建之后,不可能直接引用该对象 定义的;其

rectwo
rect
的不同之处在于
rect
是堆栈上
Rectangle
的一个实例,而
rectwo
是堆上
Rectangle
的地址。如果按值传递
Rectangle
,则会生成它的一个副本,并且您将无法进行任何更改不在
changestuff()的范围内

通过引用传递它意味着
changestuff
将具有
矩形
实例本身的内存地址,并且更改不限于
changestuff
的范围(因为
矩形

编辑:您的评论使问题更加清晰。一般来说,引用比指针更安全

来自维基百科:

在引用对象创建之后,不可能直接引用该对象 定义的;其名称的任何出现 直接指它所属的对象 参考资料

一旦创建了引用,以后就无法对其进行引用 另一个对象;无法重置它。 这通常是通过指针完成的

引用不能为null,而指针可以;每个引用都引用 对于某个对象,尽管它可能或可能 无效

无法取消初始化引用。因为无法 重新初始化引用时,它们必须 一旦它们被初始化 创建。特别是本地和 必须初始化全局变量 定义它们的位置,以及引用 哪些是类的数据成员 实例必须在 类的初始值设定项列表 构造器

此外,在堆上分配的对象可能导致内存泄漏,而在堆栈上分配的对象则不会


因此,在必要时使用指针,否则使用引用。

rectwo
rect
的不同之处在于
rect
是堆栈上的
Rectangle
的一个实例,而
rectwo
是堆上的
Rectangle
的地址。如果通过值传递
Rectangle
,则为它已创建,您将无法进行
changestuff()
范围之外的任何更改

通过引用传递它意味着
changestuff
将具有
矩形
实例本身的内存地址,并且更改不限于
changestuff
的范围(因为
矩形

编辑:您的评论使问题更加清晰。一般来说,引用比指针更安全

来自维基百科:

在引用对象创建之后,不可能直接引用该对象 定义的;其名称的任何出现 直接指它所属的对象 参考资料

一旦创建了引用,以后就无法对其进行引用 另一个对象;无法重置它。 这通常是通过指针完成的

引用不能为null,而指针可以;每个引用都引用 对于某个对象,尽管它可能或可能 无效

无法取消初始化引用。因为无法 重新初始化引用时,它们必须 一旦它们被初始化 创建。特别是本地和 必须初始化全局变量 定义它们的位置,以及引用 哪些是类的数据成员 实例必须在 类的初始值设定项列表 构造器

此外,在堆上分配的对象可能导致内存泄漏,而在堆栈上分配的对象则不会


这样,在需要时使用指针,否则引用。

< p>您需要了解引用不是指针。它们可以使用它们实现(或者它们可能不),但是C++中的引用与指针完全不同。 也就是说,任何引用了指针的函数都可以通过解引用(反之亦然)与指针一起使用。给定:

你可以说:

A a;
f1( a )
f2 ( &a );
以及:

什么时候应该使用哪一种?这取决于经验,但一般的良好实践是:

  • 尽可能在堆栈上自动分配对象,而不是使用
    new
  • 尽可能使用引用(最好是常量引用)传递对象

你需要理解引用不是指针。它们可以使用它们实现(或者它们不可以),但是C++中的引用与指针完全不同。 也就是说,任何引用了指针的函数都可以通过解引用(反之亦然)与指针一起使用。给定:

你可以说:

A a;
f1( a )
f2 ( &a );
以及:

什么时候应该使用哪一种?这取决于经验,但一般的良好实践是:

  • 尽可能在堆栈上自动分配对象,而不是使用
    new
  • 尽可能使用引用(最好是常量引用)传递对象

你没有任何理由。在C中,你只有指针。C++引入引用,通常C++中的首选方式是通过引用。它产生更简洁的语法,更简单。

让我们使用您的代码并向其中添加一个新函数:

#include <iostream>
#include "Rectangle.h"

void changestuff(Rectangle& rec);
void changestuffbyPtr(Rectangle* rec);

int main()
{
    Rectangle rect;
    rect.set_x(50);
    rect.set_y(75);
    std::cout << "x,y: " << rect.get_x() << rect.get_y() << sizeof(rect) << std::endl;
    changestuff(rect);
    std::cout << "x,y: " << rect.get_x() << rect.get_y() << std::endl;

    changestuffbyPtr(&rect);
    std::cout << "x,y: " << rect.get_x() << rect.get_y() << std::endl;

    Rectangle* rectTwo = new Rectangle();
    rectTwo->set_x(15);
    rectTwo->set_y(30);
    std::cout << "x,y: " << rectTwo->get_x() << rectTwo->get_y() << std::endl;
    changestuff(*rectTwo);
    std::cout << "x,y: " << rectTwo->get_x() << rectTwo->get_y() << std::endl;

    changestuffbyPtr(rectTwo);
    std::cout << "x,y: " << rectTwo->get_x() << rectTwo->get_y() << std::endl;
    std::cout << rectTwo << std::endl;
}

void changestuff(Rectangle& rec)
{
    rec.set_x(10);
    rec.set_y(11);
}

void changestuffbyPtr(Rectangle* rec)
{
    rec->set_x(10);
    rec->set_y(11);
}
虽然这不是:

int& b;
引用必须引用某些内容。这使得引用在多态情况下基本上不可用,在这种情况下,您可能不知道指针初始化到什么位置。例如:

// let's assume A is some interface:
class A 
{
public:
    void doSomething() = 0;
}

class B : public A
{
public:
    void doSomething() {}
}

class C : public A
{
public:
    void doSomething() {}
}

int main()
{
    // since A contains a pure virtual function, we can't instantiate it. But we can    
    // instantiate B and C
    B* b = new B;
    C* c = new C;

    // or
    A* ab = new B;
    A* ac = new C;

    // but what if we didn't know at compile time which one to create? B or C?
    // we have to use pointers here, since a reference can't point to null or
    // be uninitialized
    A* a1 = 0;
    if (decideWhatToCreate() == CREATE_B)
        a1 = new B;
    else
        a1 = new C;
}

没有任何理由你不能。在C中,你只有指针。C++介绍
 #include <iostream>
#include "Rectangle.h"

Rectangle* createARect1();
Rectangle* createARect2();

int main()
{
    // this is being created on the stack which because it is being created in main,
    // belongs to the stack for main. This object will be automatically destroyed 
    // when main exits, because the stack that main uses will be destroyed.
    Rectangle rect;

    // rectTwo is being created on the heap. The memory here will *not* be released
    // after main exits (well technically it will be by the operating system)
    Rectangle* rectTwo = new Rectangle();

    // this is going to create a memory leak unless we explicitly call delete on r1.
    Rectangle* r1 = createARectangle();

    // this should cause a compiler warning:
    Rectangle* r2 = createARectangle();
}

Rectangle* createARect1()
{
    // this will be creating a memory leak unless we remember to explicitly delete it:
    Rectangle* r = new Rectangl;
    return r;
}

Rectangle* createARect2()
{
    // this is not allowed, since when the function returns the rect will no longer
    // exist since its stack was destroyed after the function returns:
    Rectangle r;
    return &r;
}
int *b;
int& b;
// let's assume A is some interface:
class A 
{
public:
    void doSomething() = 0;
}

class B : public A
{
public:
    void doSomething() {}
}

class C : public A
{
public:
    void doSomething() {}
}

int main()
{
    // since A contains a pure virtual function, we can't instantiate it. But we can    
    // instantiate B and C
    B* b = new B;
    C* c = new C;

    // or
    A* ab = new B;
    A* ac = new C;

    // but what if we didn't know at compile time which one to create? B or C?
    // we have to use pointers here, since a reference can't point to null or
    // be uninitialized
    A* a1 = 0;
    if (decideWhatToCreate() == CREATE_B)
        a1 = new B;
    else
        a1 = new C;
}