0

这是一个简单的矩形区域计算cpp代码,我有一些问题:

#include <iostream>
#include <conio.h>
using namespace std;
class CRectangle
{
        int *width, *heigth;
    public:
        CRectangle(int, int);
        ~CRectangle();
        int area() { return (*width * *heigth);}
};

CRectangle :: CRectangle(int a, int b)
{
    width = new int;
    heigth = new int;
    *width = a;
    *heigth = b;
}

CRectangle :: ~CRectangle()
{
    delete width;
    delete heigth;
}

void main()
{
    CRectangle rect1(3,4), rect2(5,6);
    cout << "rect1 area = " << rect1.area() << "\n";
    cout << "rect2 area = " << rect2.area();
    getch();
}
  1. 为什么在这种面向对象的代码中我们使用指针,我的意思是有什么优势?
  2. rect1(3,4)在创建我们创建的对象之后的这段代码中rect2(5,6),这样做,逻辑上(我认为)5和6被替换,而不是宽度和高度指向的内存部分中的3和4,所以3和4不再可用,但他们是

请解释到底发生了什么?

4

4 回答 4

3

1-为什么在这种面向对象的代码中我们使用指针,我的意思是有什么优势?

没有了。

2、3 和 4

    width = new int;
    heigth = new int;

您总是在每个构造函数调用中保留新的单独内存位置。每个对象的宽度和高度都有单独的内存位置,因此不会被覆盖。

但是,在某些情况下,两个对象将共享相同的内存位置 - 如果您使用复制构造函数或赋值运算符将一个对象复制到另一个对象:

CRectangle rect1(3,4);
CRectangle rect2 = rect1;
CRectangle rect3(4, 5);
rect3 = rect1;

在这种情况下,widthheight获得与 's 相同的值rect1,这将使所有三个对象都指向相同的内存位置。在 的情况下rect2,不会调用默认构造函数,因此不会分配新的内存,在 的情况下, 和 的旧rect3值将丢失,并且变量将使用将引导您的内存位置进行更新到内存泄漏(因为在默认构造函数中分配的内存永远不会被释放)。widthheightrect1rect3

于 2013-09-06T17:23:56.653 回答
2

在你的情况下,指针根本没有给出任何东西。

所以指针是数组,来证明它看操作符[]内联实现。a[b]实际上是*(a + b)。因此,如果您使用new创建单个值(根据您的情况)这是不好的体验,您可以使用它来创建数组,在这种情况下的优势是使用new内存创建是在堆中分配的,以通常的方式创建分配的内存是在堆栈中.

C++ 将此留给程序员选择是否需要指针,例如,可以使用容器来获得内存分配的优势,std::vector并且这种方式不易出错。

另一件事,由于与 C 的兼容性,指针留在 C++ 中,因为有很多东西是用 C 编写的,但 C++ 开发人员也在使用它。


在宽度和高度指向的内存部分中,替换了 5 和 6 而不是 3 和 4,因此不再提供 3 和 4

看完这句话,我想你需要了解一下 C++ 或者其他面向目标的编程语言。

我的简短解释,为什么所有值都是可访问的,rect1并且rect2是完全不同的和独立的对象,所以它们有自己的记忆并且不能相互影响。


顺便说一句:忘了提到堆中分配的缺点 - 它比堆栈中的分配要慢得多。

于 2013-09-06T17:28:39.143 回答
0

为什么在这种面向对象的代码中我们使用指针,我的意思是有什么优势?

这里没有优势......这里有一些解释为什么。

有一些缺点,例如:堆上的分配比堆栈上的分配慢得多。

在创建对象 rect1(3,4) 之后的这段代码中,我们创建了 rect2(5,6) ,这样做,逻辑上(我认为)5和6被替换,而不是宽度和高度的内存部分中的3和4指向 ,所以 3 和 4 不再可用,但它们是可用的。

没有每个创建的对象都有自己的内存空间。

CRectangle rect1(3,4), rect2(5,6);

在这里,您创建了两个不同的对象。创建的第二个对象不使用第一个对象的内存。所以每个对象都有自己的空间widthheight成员。

于 2013-09-06T17:26:33.573 回答
-1

为什么在这种面向对象的代码中我们使用指针,我的意思是有什么优势?

据我们所知,这是你的主意。在这种情况下,如果有的话,优势是极其有限的。在这种情况下,它更有可能是一个劣势。

在创建对象 rect1(3,4) 之后的这段代码中,我们创建了 rect2(5,6) ,这样做,逻辑上(我认为)5和6被替换,而不是宽度和高度的内存部分中的3和4指向 ,所以 3 和 4 不再可用,但它们是可用的。

不,您对“逻辑上(我认为)5 和 6 被替换”是错误的。它们都在范围内并且在main()块结束之前有效。

以下是使它们无效的方法:

void main()
{
    {
        CRectangle rect1(3,4), rect2(5,6);
    }

    // Note that this is no longer a valid program and will fail at compile-time
    cout << "rect1 area = " << rect1.area() << "\n";
    cout << "rect2 area = " << rect2.area();
    getch();
}

如果您的问题是如何收获rect1,然后见证人rect2的堆分配恰好发生在rect1's 的位置,那么即使发生这种行为,恐怕您也不能真正指望这种行为。

于 2013-09-06T17:25:12.803 回答