首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >从构造函数调用构造函数

从构造函数调用构造函数
EN

Stack Overflow用户
提问于 2011-09-19 03:18:45
回答 2查看 239关注 0票数 2

在我下面介绍的代码中,我遇到了一个问题。它表现为一个bad_alloc异常,这是因为传递给reader ( CompressedBufferReader )的参数是一个错误的字符串。

代码语言:javascript
复制
class FileReader { 
    FILE *file; 
protected:
    unsigned char *data; // local copy
    long size;
public:
    FileReader(const char *filename);
    ~FileReader();
    unsigned long getSize();
    unsigned char *getFileData();
};

class CompressedBufferReader {
    unsigned char *buffer;
    unsigned long len;
public:
    CompressedBufferReader(unsigned char *);
    ~CompressedBufferReader();
    unsigned char *getBuffer();
    unsigned long getLength();
};
CompressedBufferReader::CompressedBufferReader(unsigned char *srcCompressed) {
    len = 0; buffer = 0;
    len = GetDecompressedBufferSize(srcCompressed);
    buffer = new unsigned char[len]; if (!buffer) throw std::runtime_error("Cannot allocate!");
    WriteDecompressedBuffer(buffer, len, srcCompressed);
}
CompressedBufferReader::~CompressedBufferReader() {
    delete[] buffer;
}
unsigned char *CompressedBufferReader::getBuffer() {return buffer;}
unsigned long CompressedBufferReader::getLength() {return len;}

// similar interface to FileReader. Does not inherit because it does not benefit from doing so.
class CompressedFileReader {
    CompressedBufferReader reader;
public:
    CompressedFileReader(const char *filename);
    unsigned char *getFileData();
    unsigned long getSize();
};

CompressedFileReader::CompressedFileReader(const char *filename) : reader(FileReader(filename).getFileData()){} // this line is causing the problem
unsigned char *CompressedFileReader::getFileData() { return reader.getBuffer(); }
unsigned long CompressedFileReader::getSize() { return reader.getLength(); }

更具体地说,我匿名创建的FileReader似乎在其数据内容被传递给reader的构造函数( CompressedBufferReader )之前就被释放了。

问题是我不能以一种允许我正确实例化FileReader的方式来编写CompressedFileReader的构造函数,因为我打算使用CompressedBufferReader的构造函数,这意味着我必须在构造函数的主体之前调用它。有点进退两难。这个问题是如何解决的?

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2011-09-19 04:55:51

我不认为您使用构造函数的方式有问题,这应该会导致bad_alloc (尽管代码看起来确实很笨拙)。让我们看一下导致问题的代码行的执行情况:

代码语言:javascript
复制
CompressedFileReader::CompressedFileReader(const char *filename) : 
   reader(FileReader(filename).getFileData()){}

执行以下步骤:

  1. 创建了一个临时FileReader。它的构造函数是通过const char*.
  2. The构造函数调用的,这是一个做未知事情的filename构造函数,因为我们没有它的代码。我假设,它应该将文件读取到分配的缓冲区中,该缓冲区存储在临时FileReader.
  3. getFileData()unsigned char *.
  4. reader,成员上,并返回data的值。我假设,这是一个使用FileReader.
  5. getFileData()构造的unsigned char *.
  6. reader,,它是一个CompressedBufferReader

因此,问题不在于构造的顺序,也不在于临时FileReader的生命周期。有几个未知之处你应该研究一下:

  1. FileReader的构造函数是否创建了有效的缓冲区,并将其存储在
    1. 中返回缓冲区?FileReader getFileData() GetDecompressedBufferSize()返回有效缓冲区的正确值?
    2. 异常是否恰好从我们没有其代码的WriteDecompressedBuffer抛出?

    < code >G241

最后,您可能希望简化代码。像这样的结构可读性不是很好。当然,使用像向量这样的标准容器会让它更安全。

票数 2
EN

Stack Overflow用户

发布于 2011-09-19 03:56:44

您的代码违反了一条非常重要的规则,即“三大规则”。

如果你的类有解构函数,赋值运算符或复制构造函数的任何,那么它应该有这三个

原因是,如果存在自定义析构函数,那么很可能自动合成的赋值操作符和复制构造函数(简单的成员间复制构造或赋值)将不是正确的操作。

这条规则非常重要,如果你碰巧发现有一个析构函数但默认的复制构造函数是有意义的,那么至少在注释中写下,你没有忘记复制构造函数和/或赋值,但自动提供的将是正确的。

相反,如果您的类不能被复制或复制构造,那么通过声明它是私有的并且不编写实现来禁止该操作。

在您的特定情况下,当您的两个类中的任何一个的实例被复制或赋值时,指针将被复制,但随后数据将被销毁两次。

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

https://stackoverflow.com/questions/7463811

复制
相关文章

相似问题

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