0

我正在为人们注册程序。

我有类 CRegister:

int personCount
int personSize
Person ** persons

结构人

char * name
char * surname
Places ** oldPlaces // here is former residence of this person

并构造 oldPlaces

char date[11]
char * street
char * city

在每个类/结构中,我都有分配空内存的构造函数,例如,方法添加了添加的人员或位置。

问题是如何实现复制构造函数?

我有这个 CRegister

CRegister::CRegister(const CRegister& b):personCount(b.personCount), personSize(b.personSize){
 persons = new Person*[b.personSize];
 personCount = 0;
 personSize = b.personSize;
 for (int i = 0; i < personSize; i++){
     persons[i] = new Person();
     persons[i].addPerson(b.persons[i]->id, b.persons[i]->name, b.persons[i]->surname);
 }

但我也想复制 oldPlaces ......

感谢您的任何建议。

4

2 回答 2

0

您还应该为数组中的每个人创建一个复制构造函数Person并使用它。

for (int i = 0; i < personSize; i++)
    persons[i] = new Person(*b.persons[i]);

并复制其中的位置:

Person::Person(const Person &b) {
    ...
    // (Note that you will have to do a deep copy for the strings here as well)
    oldPlaces = new Places *[oldPlacesCount];
    for (int i = 0; i < oldPlacesCount; i++)
        oldPlaces[i] = new Places(*b.oldPlaces[i]);
}

然后也许还为Places等创建一个复制构造函数。

编辑:是的,您需要添加oldPlacesCount.

于 2013-04-12T09:15:41.230 回答
0

std::string首先,如果您使用and ,问题或多或少会自行解决 std::vector。如果您坚持使用指针,则必须自己进行深度复制(以及赋值和析构函数)。在每个对象中,您必须访问所有指针,“克隆”子对象。 而且 您必须处理分配失败的情况,这可能会使对象的类型PersonPlaces状态不一致。要做到这一点,需要大量的代码和高度的 C++ 专业知识。你不想走那条路。(编写一个有两个指向动态分配内存的原始指针的 C++ 类可能非常复杂。使用 shared_ptrorscoped_ptr使它更简单,但仍然不像使用vectorand那样简单string。)

编辑:

只是为了弄清楚所涉及的内容 Place,如果您不使用标准库,以下是所需的内容:

struct Place
{
    char date[11];
    char* street;
    char* city;

    Place()
        : street( NULL )
        , city( NULL )
    {
        memset( date, '\0', sizeof( date ) );
    }

    Place( Place const& other )
        : street( NULL )
        , city( NULL )
    {
        memcpy( date, other.date, sizeof( date ) )
        try {
            street = new char[ strlen( other.street ) + 1 ];
            strcpy( street, other.street );
            city = new char[ strlen( other.city ) + 1 ];
            strcpy( city, other.city );
        } catch ( ... ) {
            delete [] street;
            delete [] city;
            throw;
        }
    }

    Place& operator=( Place const& other )
    {
        Place tmp( other );
        memcpy( date, other.date, sizeof( date ) );
        std::swap( street, other.street );
        std::swap( city, other.city );
        return *this;
    }

    ~Place()
    {
        delete [] street;
        delete [] city;
    }
};

Person甚至更复杂,因为您必须将整个数组初始化oldPlacesNULL,然后将其初始化为 try 块中的副本,并在出现任何问题时将其删除。

在实践中,如果由于某种原因他或她不能使用标准库,任何有 C++ 经验的人都会做的第一件事是实现 and 的(可能是简化的)版本std::stringstd::vector并使用它们。上面复制构造函数中的尝试块通常表明程序员并不真正了解 C++。上述代码中的所有分配和释放都将包装在一个更小、更原始的类中,每个类最多管理一个动态分配的资源。因此,即使与您所写的内容非常接近,也可能会开发一个StringPtr类,并在 Person 等中使用它。类似地,人们会使用一个数组Person和一个数组Place,而不是指针数组。

我不知道你的老师在多大程度上强加了你的结构,但这不是C++ 编程的方式。

于 2013-04-12T09:32:26.520 回答