关于"new"运算符的一些问题
some questions about "new" operator
这是一个计算 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();
}
- 为什么在这样的面向对象代码中使用指针,我的意思是有什么优势?
- 在创建对象
rect1(3,4)
我们创建rect2(5,6)
后的这段代码中,这样做,逻辑上(我认为)宽度和高度指向的内存部分中替换了 5 和 6 而不是 3 和 4,所以 3 和 4 不再可用,但它们是。
请解释一下到底发生了什么?
1-为什么在这样的面向对象代码中使用指针,我的意思是有什么优点?
没有。
2、3 和 4
跟
width = new int;
heigth = new int;
您始终在每个构造函数调用中保留新的单独内存位置。每个对象都有单独的宽度和高度存储位置,因此不会覆盖。
但是,在某些情况下,两个对象将共享相同的内存位置 - 如果使用复制构造函数或赋值运算符将一个对象复制到另一个对象:
CRectangle rect1(3,4);
CRectangle rect2 = rect1;
CRectangle rect3(4, 5);
rect3 = rect1;
在这种情况下,width
和 height
获得与 rect1
相同的值,这将使所有三个对象指向相同的内存位置。在 rect2
的情况下,不会调用默认构造函数,因此不会分配新的内存,而在 rect3
的情况下,width
和 height
的旧值将丢失,变量将使用rect1
的内存位置进行更新,这将导致内存泄漏(因为在 rect3
的默认构造函数中分配的内存永远不会被释放)。
在你的情况下,指针什么也没给出。
所以指针是数组,为了证明它,看看 opeator []
内联实现。 a[b]
实际上是*(a + b)
.因此,如果您使用 new
创建单个值(根据您的情况),这是不好的体验,您可以使用它来创建数组,在这种情况下的优势是使用new
内存创建是在堆中分配的,以通常的方式创建内存分配在堆栈中。
C++留给程序员选择他们是否需要指针,可以使用容器(例如std::vector
)获得内存分配的优势,并且这种方式更不容易出错。
另一件事,由于与 C 的兼容性,指针留在C++中,因为有很多东西是用 C 编写的,但C++开发人员也使用它。
在宽度和高度指向的内存部分中,5 和 6 被替换而不是 3 和 4,因此 3 和 4 不再可用
读完这句话,我认为你需要阅读C++或其他客观的编程语言。
我的简短解释,为什么所有值都是可访问的,rect1
和rect2
是完全不同的和独立的对象,所以它们有自己的记忆,不能相互影响。
顺便说一句:忘了提到堆中分配的缺点 - 它比堆栈中的分配慢得多。
为什么在这样的面向对象代码中使用指针,我的意思是有什么优势?
这里没有优势...以下是一些解释。
有一些缺点,例如:堆上的分配比堆栈上的分配慢得多。
在创建对象 rect1(3,4) 后的这段代码中,我们创建了 rect2(5,6),这样做,逻辑上(我认为)宽度和高度指向的内存部分中替换了 5 和 6 而不是 3 和 4,所以 3 和 4 不再可用,但它们是。
没有 创建的每个对象都有自己的内存空间。
CRectangle rect1(3,4), rect2(5,6);
在这里,您可以创建两个不同的对象。创建的第二个对象不使用第一个对象的内存。因此,每个对象都有自己的空间供width
和height
成员使用。
为什么在这样的面向对象代码中使用指针,我的意思是有什么优势?
据我们所知,这是你的主意。 在这种情况下,优势非常有限,如果有的话。 在这种情况下,这更有可能是一个缺点。
在创建对象 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
的位置,那么恐怕即使你让它发生,你也不能真正指望这种行为。
- 一个关于在C++中重载布尔运算符的问题
- 使用运算符 [] 引用 std::vector 上最后一个元素时出现问题<>
- 运算符继承和 cpp 核心准则 c.128 的问题
- 在C++中使用重载提取运算符时出现问题
- 移动赋值运算符;尝试引用已删除的函数.我该如何解决这个问题?
- 关于条件块的问题与&&运算符有关
- 重载运算符与添加问题
- 加、乘、除、减复数的问题 C++ - 运算符重载
- 我需要这方面的帮助C++在使用逻辑运算符时是/否问题
- 0xC0000005:访问冲突读取位置 0x00000000. 重载 == 运算符的问题
- 如何解决不明确的运算符过载问题?
- 屏幕插入运算符<<的运算符过载问题
- 如何通过使用 2 位或更多数字的 XOR 运算符来执行此操作C++问题
- 在 C++ 的自定义运算符中删除与删除[](不同于常见的删除与删除[]问题)
- 用户定义的文本运算符(在原始模式下)存在问题
- 关于重载 -> 运算符中 const 关键字的特定位置的问题
- 字符 * 未从重载运算符或内存管理问题正确返回
- constexpr 运算符重载使用参数的问题
- c++中重载输入运算符的问题
- 有趣的问题运算符重载