首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >复制构造函数和动态内存

复制构造函数和动态内存
EN

Stack Overflow用户
提问于 2017-02-08 00:06:40
回答 3查看 2.9K关注 0票数 2

我是一个编程的初学者,我正在学习有关复制构造函数。从不同的来源我可以看到,如果我想要“深拷贝”一个类对象,那么复制构造函数是有用的,这样新对象的指针成员就会指向新的内存位置。

我的问题是,如果我在一个空的复制构造函数(如在类CopyCat中)中得到相同的结果,那么定义复制构造函数的好处是什么?

我的第二个问题是,为什么类猫和类EmptyCat的工作方式不同?它们之间唯一的区别是,我在EmptyCat中定义了一个空的复制构造函数。但是,当我运行程序时,我可以看到在EmptyCat中,在复制指针成员之后指向一个新位置,而在类Cat中,它作为一个浅拷贝工作。

代码语言:javascript
复制
#include "iostream"

class Cat
{
  public:
    void GetMem() { std::cout << itsAge << "\n"; }
  private:
    int * itsAge = new int;
};

class EmptyCat
{
  public:
    EmptyCat() {}
    ~EmptyCat() {}
    EmptyCat(EmptyCat&obj) {}
    void GetMem() { std::cout << itsAge << "\n"; }
  private:
    int * itsAge = new int;
};

class CopyCat
{
  public:
    CopyCat() {}
    ~CopyCat() {}
    CopyCat(CopyCat&obj);
    int GetAge() { return *itsAge; }
    void GetMem() { std::cout << itsAge << "\n"; }
  private:
    int * itsAge = new int;
};

CopyCat::CopyCat(CopyCat & obj)
{
    itsAge = new int;
    *itsAge = obj.GetAge();
}

int main()
{
    Cat Garfield;
    Cat Kitty(Garfield);

    std::cout << "Memory addresses for the objects' <itsAge> member:" << std::endl;
    std::cout << "Garfield and Kitty (Class Cat):" << std::endl;
    Garfield.GetMem();
    Kitty.GetMem();

    EmptyCat Meow;
    EmptyCat Purr(Meow);

    std::cout << std::endl << "Meow and Purr (Class EmptyCat):" << std::endl;
    Meow.GetMem();
    Purr.GetMem();

    CopyCat Fluffy;
    CopyCat Felix(Fluffy);

    std::cout << std::endl << "Fluffy and Felix (Class CopyCat):" << std::endl;
    Fluffy.GetMem();
    Felix.GetMem();

    system("pause");
    return 0;
}

如果我运行这个程序,我会得到这样的信息:

代码语言:javascript
复制
Memory addresses for the objects' <itsAge> member:
Garfield and Kitty (Class Cat):
00BBDA60
00BBDA60

Meow and Purr (Class EmptyCat):
00BB46A0
00BB8280

Fluffy and Felix (Class CopyCat):
00BB82B0
00BBE8A0
Press any key to continue . . .
EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2017-02-08 00:36:51

我的问题是,如果我在一个空的复制构造函数(如在类CopyCat中)中得到相同的结果,那么定义复制构造函数的好处是什么?

你不可能得到同样的结果。CopyCat分配新内存并从旧类复制值。EmptyCat只分配新内存,但不复制值。

我的第二个问题是,为什么类猫和类EmptyCat的工作方式不同?它们之间唯一的区别是,我在EmptyCat中定义了一个空的复制构造函数。但是,当我运行程序时,我可以看到在EmptyCat中,在复制指针成员之后指向一个新位置,而在类Cat中,它作为一个浅拷贝工作。

Cat中,您还没有声明一个复制构造函数,所以编译器会在需要时生成一个。默认副本构造函数从原始副本执行成员级复制。在您的示例中,这将复制指针(以便它存储与原始指针相同的地址)。

EmptyCat中,有一个用户定义的复制构造函数。但是,由于该指针不处理指针成员,因此将使用它的默认值。

代码语言:javascript
复制
int * itsAge = new int;

这就是分配新int并为您获取不同指针值的内容。

票数 1
EN

Stack Overflow用户

发布于 2017-02-08 00:25:22

深度复制和浅层复制是一个C概念,只有结构和原始指针。可以拥有指针,在这种情况下,副本必须是深的,或者可以共享,在这种情况下,副本是浅的(如果用malloc分配的话,您必须小心释放它)。

在C++中,new现在实际上已不再受欢迎。我们有唯一的指针,它们是“拥有指针”和“共享指针”。然而,指针相对较少。类的数组成员是std::vectors,string成员是std::string。并且副本自动深,(如果您想要一个浅拷贝,可以使用引用)。

指针被限制在相对不寻常的情况下,比如树木和图表。

票数 2
EN

Stack Overflow用户

发布于 2017-02-08 00:14:04

在没有空副本构造函数的情况下,您不会得到相同的行为。EmptyCat(EmptyCat& obj) { }绝对什么都不做。

代码语言:javascript
复制
CopyCat(CopyCat& obj) {
  itsAge = new int;
  *itsAge = obj.GetAge();
}

动态地分配一个新的int并从obj分配一个值给它。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/42102332

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档