通过引用返回/传递动态分配的对象

Returning/Passing an dynamically allocated object by Reference

本文关键字:动态分配 对象 引用 返回      更新时间:2023-10-16

我现在在我的抽象数据类型中遇到了这个问题。基本上它应该像 c++ 中通常的字符串类一样,所以不要被我的 ADT 中的数字混淆。我在创建动态分配的对象时遇到问题。(我相信在下面的代码中正确实现)然后,我需要调用引用String346对象的 concat 函数。

同样在此代码中,我应该返回一个引用。如果有人可以向我解释如何使用它以及如何以正确的方式返回它的概念,请告诉我,因为我在许多函数中返回对String346的引用。

这是重载/默认构造函数(数据是char *sizeunsigned int):

String346::String346(const char * oldString = "") : size(strlen(oldString)) {
        strcpy(data, oldString);
    }

这是我为传入的String346对象编写concat函数的代码(没有编写任何内容,因为我还没有计划如何执行此操作):

String346 & String346::concat(const String346 & catString){
    }

这就是我感到困惑的地方。这是我使用 char 指针的concat函数。当前段concat(&newCatString);是错误的,不适用于上述函数。

    String346 & String346::concat(const char * catString){
    String346 * newCatString = new (std::nothrow) String346(catString);
    concat(&newCatString);
}

如果您需要其他任何东西,请告诉我。我相信这就是你需要的,你不需要知道更多。

你考虑

的方式是错误的。 您不会动态分配新对象。 动态(重新)分配要分配/连接到的对象的数据,然后返回对该对象的引用,而不是对新分配对象的引用。

如果你真的想在一个类似字符串的类中手动实现这一点(而不是使用标准的std::string类),那么尝试更像这样的东西:

class String346 {
private:
    char *data;
    unsigned int size;
public:
    String346();
    String346(const char *oldString);
    String346(const String346 &oldString);
    ~String346();
    //...
    String346& operator=(const String346 &newString);
    //...
    String346& concat(const String346 &catString);
    //...
};

String346::String346() : data(NULL), size(0) {
}
String346::String346(const char * oldString) : data(NULL), size(std::strlen(oldString)) {
    data = new char[size+1];
    std::copy_n(oldString, size, data);
    data[size] = 0;
}
String346::String346(const String346 &oldString) : data(NULL), size(oldString.size) {
    data = new char[size+1];
    std::copy_n(oldString.data, size, data);
    data[size] = 0;
}
String346::~String346() {
    delete[] data;
}
String346& operator=(const String346 &newString) {
    String346 tmp(newString);
    std::swap(data, tmp.data);
    size = tmp.size;
    return *this;
}
String346 & String346::concat(const String346 &catString) {
    String346 tmp;
    tmp.size = size + catString.size;
    tmp.data = new char[tmp.size+1];
    std::copy_n(data, size, tmp.data);
    std::copy_n(catString.data, catString.size, tmp.data+size);
    tmp.data[tmp.size] = 0;
    std::swap(data, tmp.data);
    size = tmp.size;
    return *this;
}

从技术上讲,您不必实现 operator=()concat()char*版本,因为它们都const String346&作为输入,并且String346有一个接受char*作为输入的构造函数。 如果将char*传递给其中一个,编译器将自动为您构造和销毁一个临时String346对象:

String346 s;
s = "hello"; // calls s.operator=(String346("hello"))...
s.concat("world"); // calls s.concat(String346("world"))...

但是,出于优化目的,这样做可能是有意义的,以避免不必要的临时内存分配(除非您在 C++11 中实现移动语义):

class String346 {
private:
    char *data;
    unsigned int size;
public:
    String346();
    String346(const char *oldString);
    String346(const String346 &oldString);
    ~String346();
    //...
    String346& operator=(const char *newString);
    String346& operator=(const String346 &newString);
    //...
    String346& concat(const char *catString);
    String346& concat(const String346 &catString);
    //...
};

String346::String346() : data(NULL), size(0) {
}
String346::String346(const char * oldString) : data(NULL), size(std::strlen(oldString)) {
    data = new char[size+1];
    std::copy_n(oldString, size, data);
    data[size] = 0;
}
String346::String346(const String346 &oldString) : data(NULL), size(oldString.size) {
    data = new char[size+1];
    std::copy_n(oldString.data, size, data);
    data[size] = 0;
}
String346::~String346() {
    delete[] data;
}
String346& operator=(const char *newString) {
    String346 tmp(newString);
    std::swap(data, tmp.data);
    size = tmp.size;
    return *this;
}
String346& operator=(const String346 &newString) {
    String346 tmp(newString);
    std::swap(data, tmp.data);
    size = tmp.size;
    return *this;
}
String346 & String346::concat(const char *catString) {
    unsigned int catSize = std::strlen(catString);
    String tmp;
    tmp.size = size + catSize;
    tmp.data = new char[tmp.size+1];
    std::copy_n(data, size, tmp.data);
    std::copy_n(catString, catSize, tmp.data+size);
    tmp.data[tmp.size] = 0;
    std::swap(data, tmp.data);
    size = tmp.size;
    return *this;
}
String346 & String346::concat(const String346 & catString) {
    String tmp;
    tmp.size = size + catString.size;
    tmp.data = new char[tmp.size+1];
    std::copy_n(data, size, tmp.data);
    std::copy_n(catString.data, catString.size, tmp.data+size);
    tmp.data[tmp.size] = 0;
    std::swap(data, tmp.data);
    size = tmp.size;
    return *this;
}