简体   繁体   English

复制构造函数析构函数和赋值运算符,用于存储指向另一个类的指针的类

[英]Copy constructor destructor and assignment operator for class storing pointers to another class

I'm new here and this is my first question. 我是新来的,这是我的第一个问题。 I have a question about my homework assignment. 我对我的家庭作业有疑问。 I'm asked to design an abstract class "Base" which is inherited by the class "Sub" (in the assignment there are sub1, sub2 etc but I have tried to narrow it down as much as possible). 我被要求设计一个抽象类“Base”,它由类“Sub”继承(在赋值中有sub1,sub2等,但我试图尽可能地缩小它)。 Then, I should design a class "BasePtr" which stores a pointer to a "Base" object. 然后,我应该设计一个类“BasePtr”,它存储一个指向“Base”对象的指针。 Finally, baseptr:s are to be stored in a std::vector, and written to a file using ostream_iterator and copy. 最后,baseptr:s将存储在std :: vector中,并使用ostream_iterator和copy写入文件。 The file should then be read with a ifstream_iterator, and stored in a std::list. 然后应该使用ifstream_iterator读取该文件,并将其存储在std :: list中。

I have solved the above problem, but I have some problems when implementing the destructor, copy constructor and assignment operator (since I am dynamically allocating memory in my BasePtr class I believe that those should be present). 我已经解决了上面的问题,但是在实现析构函数,复制构造函数和赋值运算符时遇到了一些问题(因为我在BasePtr类中动态分配内存,我相信那些应该存在)。

This is the main program. 这是主要计划。

#include <vector>
#include <fstream>
#include <iterator>
#include <list>
#include "baseptr.h"

using namespace std;
int main()
{  
    vector<BasePtr> basevec;
    basevec.push_back( BasePtr(new Sub(1, 4)) );
    basevec.push_back( BasePtr(new Sub(3, 5)) );

    ofstream os("fil.dat");
    ostream_iterator<BasePtr> baseout(os,"\n");
    copy( basevec.begin(), basevec.end(), baseout);
    os.close();

    ifstream is("fil.dat");
    istream_iterator<BasePtr> basein(is), endofbasein;
    list<BasePtr> baselist(basein, endofbasein );

    for (list<BasePtr>::iterator it = baselist.begin(); it != baselist.end(); it++) 
        cout << *it << endl;    
}

The BasePtr class BasePtr类

#include <iostream>
#include <string>
#include "base.h"

using namespace std;

class BasePtr {
public: 
    BasePtr() : basevar(0) {}
    BasePtr(Base *bin) {basevar = bin->clone(); delete bin;}
    const BasePtr & operator=( BasePtr & baseptr ); // assignment operator
    BasePtr(const BasePtr &baseptr ); // copy constructor
    ~BasePtr(); // destructor
    friend ostream& operator<<( ostream &os, const BasePtr &baseptr); 
    friend istream& operator>>( istream &is, BasePtr &baseptr); 
private:
    Base* basevar;
};

const BasePtr & BasePtr::operator=( BasePtr & baseptr ) {
    if (this != &baseptr) {
        delete basevar;
        basevar = baseptr.basevar->clone();
    }
    return *this;
}

BasePtr::BasePtr( const BasePtr &baseptr ) {
    if (baseptr.basevar != 0)
        basevar = baseptr.basevar->clone();
}

BasePtr::~BasePtr() {
    if ( basevar != 0 )
        delete basevar;
    basevar = 0;
}

ostream& operator<<( ostream &os, const BasePtr &baseptr) {
    os << *baseptr.basevar;
    return os;
}

istream& operator>>( istream &is, BasePtr &baseptr) {
    string name;
    if (!(is >> name))
        return is;
    Base *b = 0;
    if ( name == "SUB" ) 
        b = new Sub();  
    is >> *b;
    baseptr.basevar = b->clone();
    delete b;
    return is;
}

and the Base and Sub classes 以及Base和Sub类

#include <iostream>
using namespace std;

class Base {
public: 
    virtual ~Base() {}
    virtual Base* clone() const = 0; 
    friend ostream& operator<<( ostream &os, Base &b) {
        b.print(os); 
        return os;}
    friend istream& operator>>( istream &is, Base &b) {b.readStream(is); return is;}
protected:
    Base(const double xin) : x(xin) {}
    double x;
    virtual ostream& print(ostream &os) const = 0; 
    virtual void readStream( istream &is ) = 0;

};


class Sub : public Base{
public:
    Sub() : Base(0), size(0) {}
    Sub(double xin, double si) : Base(xin), size(si) {}
    ~Sub() {};
    Sub* clone() const {return new Sub(*this);}
private:
    double size;
    Sub(const Sub &p) : Base(p.x), size(p.size) {}
protected:
    virtual ostream& print(ostream &os) const {os << "SUB " <<  x << " " << size << endl; 
        return os; }
    virtual void readStream( istream &is ) {
        is >> x;
        is >> size;
    }

};

If I comment out the destructor, copy constructor and assignment operator the program builds and runs, and outputs the desired result. 如果我注释掉析构函数,复制构造函数和赋值运算符,程序就会构建并运行,并输出所需的结果。 However, valgrind finds loads of memory leaks (obviously). 但是,valgrind发现了大量内存泄漏(显然)。 If I include these functions, the program ends with Segmentation fault: 11. I am using a mac with os x 10.8 and the clang compiler. 如果我包含这些函数,程序以Segmentation fault结束:11。我使用的是带有os x 10.8的mac和clang编译器。 What am I doing wrong? 我究竟做错了什么?

The bug in your program is probably in the copy constructor: 您的程序中的错误可能在复制构造函数中:

BasePtr::BasePtr( const BasePtr &baseptr ) {
    if (baseptr.basevar != 0)
        basevar = baseptr.basevar->clone();
    else {
        basevar = 0; // <<<< missing
    }
}

Without this change the following code will produce errors: 如果没有此更改,以下代码将产生错误:

BasePtr a; // a.basevar = 0
BasePtr b = a; // now b.basevar is not initialized
// destruction of b will call delete on an uninitialized pointer

You aren't initializing basevar in your BasePtr copy constructor, change it to the following: 您没有在BasePtr复制构造函数中初始化basevar ,将其更改为以下内容:

BasePtr::BasePtr( const BasePtr &baseptr ) : basevar{} {
    if (baseptr.basevar != 0)
        basevar = baseptr.basevar->clone();
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 C ++是否为纯虚拟类创建默认的“构造函数/析构函数/复制构造函数/复制赋值运算符”? - Does C++ create default “Constructor/Destructor/Copy Constructor/Copy assignment operator” for pure virtual class? 类分配运算符和副本构造函数 - Class assignment operator and copy constructor 禁止复制构造函数和赋值运算符singleton类 - prohibit copy constructor and assignment operator singleton class 复制构造函数,赋值运算符和析构函数代码重复 - Copy constructor, assignment operator, and destructor code duplication 在派生的 class 中定义析构函数需要复制赋值运算符 - Defining destructor in derived class requires copy assignment operator 是否有必要为具有另一个类 B 的数据成员的类 A 重载赋值运算符和复制构造函数? - Is it necessary to overload the assignment operator and the copy constructor for a class A which has a data member of another class B? 如何使用类对象上的指针在类中定义复制构造函数和=运算符覆盖? - How to define copy constructor and = operator override in class with pointers on class object? 链表:如何实现析构函数、复制构造函数和复制赋值运算符? - Linked List: How to implement Destructor, Copy Constructor, and Copy Assignment Operator? 如何在具有指向对象的指针的数组的类中创建复制构造函数和析构函数,其中对象本身具有指向int的指针的数组 - How to create copy constructor and destructor in a class with an array of pointers to objects where objects itself have an array of pointers to ints 在具有智能指针的类上正确实现Copy构造函数和Equals运算符 - Proper Implementation of Copy Constructor and Equals Operator on a class with smart pointers
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM