关于“新”算子的一些问题

时间:2013-09-06 17:21:02

标签: c++

这是一个计算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)之后
  3. 创建rect2(5,6),这样做,逻辑上(我认为)5和6被替换而不是3和4在内存部分的宽度和高度指向,所以3和4不再可用,但它们
  4. 请解释究竟发生了什么?

4 个答案:

答案 0 :(得分:3)

  

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

没有。

  

2,3和4

    width = new int;
    heigth = new int;

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

但是,有一种情况是两个对象将共享相同的内存位置 - 如果使用copy-constructor或赋值运算符将一个对象复制到另一个对象:

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

在这种情况下,widthheight获得与rect1相同的值,这将使所有三个对象指向相同的内存位置。在rect2的情况下,将不会调用默认构造函数,因此不会分配新的内存,如果是rect3,则会调用width和{{1}的旧值。 }将丢失,变量将使用height的内存位置进行更新,这将导致内存泄漏(因为永远不会释放rect1的默认构造函数中分配的内存)。 / p>

答案 1 :(得分:2)

在你的情况下,指针根本没有提供任何内容。

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

C ++让程序员选择是否需要指针,可以使用容器来实现内存分配的优势,例如std::vector,这种方式更容易出错。

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


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

读完这句话后,我认为你需要阅读C ++或其他客观的编程语言。

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


BTW:忘了提到堆中分配的缺点 - 它比堆栈中的分配慢得多。

答案 2 :(得分:0)

  

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

这里没有优势...... Here是一些解释原因。

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

  

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

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

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

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

答案 3 :(得分:-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的位置,那么我恐怕你不能即使你有这种行为,也要依靠这种行为。