gpt4 book ai didi

c++ - 关于复制构造函数和指针

转载 作者:塔克拉玛干 更新时间:2023-11-03 08:14:24 24 4
gpt4 key购买 nike

我正在通读 primer 中的一个示例,但其中提到的内容并没有发生。具体来说,任何隐式浅拷贝都应该复制指针的地址,而不仅仅是所指向的值(因此是相同的内存地址)。但是,每个 pos 属性都指向两个不同的内存地址(因此我可以在不影响另一个的情况下更改一个的值)。我做错了什么?

标题

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

class Yak
{
public:
int hour;
char * pos;
const Yak & toz(const Yak & yk);
Yak();
};

结束标题

using namespace std;
const Yak & Yak:: toz(const Yak & yk)
{
return *this;
}

Yak::Yak()
{
pos = new char[20];

}

int _tmain(int argc, _TCHAR* argv[])
{
Yak tom;
tom.pos="Hi";

Yak blak = tom.toz(tom);


cout << &blak.pos << endl;
cout << &tom.pos << endl;


system("pause");
return 0;
}

最佳答案

您正在打印指针的地址,而不是它们指向的字符串的地址:

cout << &blak.pos << endl;
cout << &tom.pos << endl;

它们是两个不同的指针,所以它们的地址不同。但是,它们指向相同的字符串:

cout << static_cast<void*>(blak.pos) << endl;
cout << static_cast<void*>(tom.pos) << endl;

(请注意强制转换 static_cast<void*>(tom.pos) 。正如亚伦在评论中指出的那样,这是必要的,因为当输出 char* 将通过 operator<< 时,流库将假定指向的字符是一个以零结尾的字符串。输出一个 void* ,OTOH,将输出地址。)


请注意,您的代码有更多错误。这里

Yak tom;

您正在创建一个新对象。它的构造函数分配了20个字符,并将它们的地址存储在tom.pos中。 .在下一行

tom.pos="Hi";

您正在将字符串文字的地址分配给 tom.pos ,从而丢弃您分配的字节地址,有效地泄漏该内存。

另请注意 Yak没有析构函数,所以即使你不以这种方式丢弃 20 个字符,当 tom超出范围,tom.pos将被销毁,因此这 20 个字节的地址将丢失。

但是,由于缺少复制构造函数,当您复制 Yak对象,你最终得到他们中的两个有他们的 pos指向同一分配内存的元素。当他们超出范围时,他们都会尝试删除该内存,这是致命的。


为了缩短这段时间:使用 std::string .这要容易得多。掌握基础知识,使用语言的安全功能,如 std::string ,标准库的容器,智能指针。一旦您确定了这些,就可以解决手动内存管理问题。

但是,请记住,我从事 C++ 工作大约 15 年,认为手动资源管理(内存只是一种资源)容易出错并尽量避免。如果必须这样做,我会将每个资源隐藏在管理它的对象后面——有效地退回到自动内存管理。 :)


您正在阅读的是哪本“入门书”? Lippmann 的 C++ Primer?如果有,是哪个版本?如果 Lippmann 的书的最新版本让您迷失在动态内存上而没有首先向您展示解决这个问题的工具以及如何使用它们,我会感到惊讶。

关于c++ - 关于复制构造函数和指针,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3241307/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com