在char数组包装类中实现C ++ setter的正确方法是什么?

时间:2011-05-22 09:24:56

标签: c++ operator-overloading setter

我正在处理只包含字符数组的类及其大小(以字节为单位的长度)。目前,我想为这个类重载'+'操作数(实现连接)。构造函数工作正常。创建对象,我可以在调试器中看到它们的字段和值。我被困在使用'+'的位置(主要(第13行))。代码编译得很好,甚至没有警告,但是当我运行它时,我的程序失败了“无效指针消息”。我找到了无效指针的位置。它在'+'实现中(BufferArray.cpp,第39行)。当我调用SetBuffer时,char数组被正确分配(我在运算符实现范围中看到它的值'qwasd'),但是当我调用SetSize时,它在下一行时消失了。我不明白为什么。

我的setter有什么问题,在这种情况下如何实现'+'操作数?

提前致谢。

以下是我使用的代码:

BufferArray.h:

#include <string.h>
#include <stdio.h>

#ifndef BUFFERARRAY_H
#define BUFFERARRAY_H
class BufferArray {
public:
    BufferArray(char* reservedPlace);
    BufferArray();
    void SetSize(int sz);
    int GetSize();
    void SetBuffer(char* buf);
    char* GetBuffer();
    BufferArray operator+ (BufferArray bArr) const;
    virtual ~BufferArray();
private:
    int size;
    char *buffer;
};

#endif  /* BUFFERARRAY_H */

实施位于下一个文件 BufferArray.cpp:

#include "BufferArray.h"

// Constructors.
BufferArray::BufferArray(){
    size = 0;
    strcpy(buffer, "");
}
BufferArray::BufferArray(char* reservedPlace) {
    size = strlen(reservedPlace);
    buffer = reservedPlace;
}

// Getters and setters.
void BufferArray::SetSize(int sz)
{
    size = sz;
}
int BufferArray::GetSize()
{
    return size;
}
void BufferArray::SetBuffer(char* buf)
{
    buffer = buf;
}
char* BufferArray::GetBuffer()
{
    return buffer;
}

// Operator +.
BufferArray BufferArray::operator+ (BufferArray bArr) const
{
    char tempCharArray[strlen(buffer) + strlen(bArr.GetBuffer())];
    strcpy(tempCharArray, buffer);
    strcat(tempCharArray, bArr.GetBuffer());
    BufferArray tempBA;
    tempBA.SetBuffer(tempCharArray);
    tempBA.SetSize(strlen(bArr.GetBuffer()) + strlen(buffer)); // Vanishes buffer field.
    printf("%d",tempBA.GetSize());
    return tempBA;
}

// Destructor.
BufferArray::~BufferArray() {
    // Destroy the pointer.
    delete [] buffer;
}

主要功能:

#include <cstdlib>
#include <iostream>
#include "BufferArray.h"
using namespace std;

int main(int argc, char** argv) {
    BufferArray ba1;
    char tmp1[3] = "qw";
    char tmp2[4] = "asd";
    ba1.SetSize(strlen(tmp1));
    ba1.SetBuffer(tmp1);
    BufferArray ba2(tmp2);
    BufferArray ba3 = ba1 + ba2;           // Runtime error is here.
    cout << ba3.GetBuffer() << endl;
    return 0;
}

2 个答案:

答案 0 :(得分:4)

在BufferArray :: operator +中的

,tempCharArray是一个临时缓冲区,在函数完成时将被销毁。有两种方法可以解决这个问题:

1 /在operator +中使用new []分配临时缓冲区,这样你就可以确保缓冲区在对operator +的调用中幸存下来但是你要么有内存泄漏,要么调用者稍后调用delete [] ,这是相当笨拙和容易出错的

2 /或更好,修改setBuffer,使其执行缓冲区的内部副本,并在您自己的析构函数中添加对delete []的调用:

BufferArray::~BufferArray() {
    delete[] buffer;
}

void BufferArray::setBuffer(char *otherBuffer) {
    buffer = new char[strlen(otherBuffer) + 1];
    strcpy(buffer, otherBuffer);
}

请注意,您必须修改构造函数,以便它还复制输入缓冲区(否则,当对象被销毁时,您将非法调用delete []),然后您可能需要重载复制 - 构造函数和赋值运算符,以防止浅拷贝,这将导致双重删除缓冲区。

在实际的生产代码中,你想要使用某种托管指针来避免自己进行删除(例如std :: vector或boost :: shared_array),但对于作业,上面的解决方案应该没问题。 / p>

另外,在使用strlen确定缓冲区大小时,不要忘记添加+1;)

答案 1 :(得分:1)

您需要使用new来创建这些char数组,否则当您退出范围时,临时值(如tempBA)将被销毁。

void BufferArray::SetBuffer(char* buf)
{
   buffer = new char[strlen(buf)+1]; //edit, my size param wasn't necessary
   strcpy(buffer,buf);
}