0

我只是想确定我是否理解指针的属性。所以,如果我有这样的事情:

#include <iostream>
using namespace std;

class Person
{
public:
  Person(){myBook = new Book(4);}
  void printPerson()
  {
    int i =0;
    while(i<n)
    {
        cout<<myBook[i].n<<endl;
        i++;
    }
  }

private:
   Book *myBook;
   int n;
};

class Book
{
public:
  Book(int num)
  {
      int n =0;
  }  
  int n;
  };

由于 Person 类的实例是一个指针,所以当我尝试创建一个复制构造函数和赋值 operator= 时,我必须为新的 Person 对象分配一个新的 Book。我对吗?谢谢

4

2 回答 2

4

这里有一个错误:

Person(){myBook = new Book(4);}

分配一个 Book 对象num=4,如果您要分配 4 个 Book 元素,请执行以下操作:

Person(){myBook = new Book[4];}

否则当您myBook[i]在 while 循环中访问时是未定义的行为:

while(i<n)
{
   cout<<myBook[i].n<<endl;
               ^^^ ouch
   i++;
}

由于 Person 类的实例是一个指针,所以当我尝试创建一个复制构造函数和赋值 operator= 时,我必须为新的 Person 对象分配一个新的 Book。我对吗?

是的,请确保您遵循三原则

其他建议是,如果可以的话,使用std::vector代替动态数组,使用智能指针代替原始指针。

于 2013-02-14T22:15:31.637 回答
1

(在假设下,您的意思是书的实例,而不是人的实例)

为了制作一个人的深层副本,您还需要创建一个新的书籍实例。使用深拷贝可以让您破坏原始人物及其书籍,同时保留副本和复制的书籍。

有一些用例,您实际上希望两个人都指向同一个书对象。

在这种情况下,您需要使用诸如共享指针之类的东西来跟踪有多少指针指向书本。

编辑以清除它:如果您有不止一个人拥有同一本书,并且您对该人有一个有效的析构函数:

class Person {
public:
  ~Person() {
    delete m_pbook;
  }
protected:
  Book *m_pbook;
}

class Book {
  int foo;
}

Person a = new Person();  // book pointer is something like 0x12345678
Person b = new Person(a); // book pointer is identical 0x12345678

// delete a yields
delete a; // memory in 0x12345678 is freed up
b->book;  // AccessViolation / Segmentation Fault, the memory in 0x12345678 does not belong to your program any more.
于 2013-02-14T22:14:25.307 回答