我只是想确定我是否理解指针的属性。所以,如果我有这样的事情:
#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。我对吗? THX
答案 0 :(得分:4)
这里有一个错误:
Person(){myBook = new Book(4);}
使用num=4
分配一个Book对象,如果您要分配4个Book元素,请执行:
Person(){myBook = new Book[4];}
否则当您访问myBook[i]
时,while循环是未定义的行为:
while(i<n)
{
cout<<myBook[i].n<<endl;
^^^ ouch
i++;
}
由于Person类的实例是一个指针,当我尝试创建一个复制构造函数和赋值operator =时,我必须为新的Person对象分配一个新的Book。我是对的吗?
是的,请务必遵循rule of three
其他建议是,使用std::vector代替动态数组,如果可以,请使用智能指针而不是原始指针。
答案 1 :(得分: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.