如何通过值 C++ 传递 char*?

时间:2021-03-22 10:53:17

标签: c++ arrays string reference char

我定义了一个 char* content 类型的属性,它接受一个字符串,该字符串甚至包含 \0 之类的字符,这样我就无法使用 string 类型。

当我尝试为内容定义 setter 时,这里的问题是:

void MyClass::setContent(char* content)
{
    if(this->contentLength!=0){
        if(this->content)
            free(this->content);
        this->content = (char*)malloc(this->contentLength);
        memset(this->content,0,this->contentLength);
        memcpy(this->content,content,this->contentLength);
    }
}

知道 contentLength 也是 MyClass 的一个属性。

但是在另一个堆栈中,我定义了一个返回 MyClass 对象的函数:

MyClass myfunction(args) {
    MyClass myclass;
    /**
     *Do some stuff on myclass
     */
    return myclass;
}

在另一个堆栈上,我已经定义了这个:

MyClass element = myFunction(args);

这里我丢失了内容,因为它总是指向第一个堆栈中 myclass 的地址。

如何将 content 复制到新对象 element

我正在研究 C++98,但无法实施 c++11 上的任何解决方案。

3 个答案:

答案 0 :(得分:2)

https://en.cppreference.com/w/cpp/language/copy_constructor 当您按值返回对象时,会调用复制构造函数来复制您的对象。

如果不手动创建,则会生成默认的复制构造函数。它只是复制指针,所以两个指针指向同一个数组。

您可以像这样手动创建一个复制构造函数:

MyClass(const MyClass& other)
{
    this->contentLength = other.contentLength;
    this->content = (char*) malloc(this->contentLength);
    memcpy(this->content, other.content, this->contentLength);

    // Copy every other field manually here, if you have any.
}

更新: 请参阅 eerorika 和 Peter 的回答以了解更好的做法以及如何避免这种需求。

答案 1 :(得分:2)

<块引用>

我定义了一个 char* 类型的属性,它接受一个字符串,该字符串甚至包含 \0 之类的字符,

你的问题就在那里。如果您传递一个 char * - 更糟糕的是,使用它来管理由 malloc() 返回的动态分配的内存,有很多事情可能会出错。

简单地传递一个 std::vector<char>。它跟踪自己的长度,不关心它包含多少 '\0' 值,并且可以根据需要动态调整大小。例如,您可以重新实现

void MyClass::setContent(const std::vector<char> &content)
{
    this->content = content;    // this will copy all of the characters
                                //  from content to this-content
                                //  and manage memory for you
}

有大量关于 std::vector 的文档,例如 cppreference vector page,解释了 vector 支持哪些操作。只要您不厌其烦地正确使用它的操作(它不是免费的),std::vector<char> 将使您的生活更轻松。尽管 C++ 标准之间的 std::vector 有一些演变,但即使是 C++98 版本也应该足以满足您的需求。

答案 2 :(得分:2)

<块引用>

如何通过值 C++ 传递 char*?

与其他类型按值传递的方式相同:不要使用引用参数。示例:

void function_name(char*); // the pointer will be passed by value
<块引用>

如何将 content 复制到新的对象元素?

这就是你所做的。您复制了指针,因此副本指向同一个数组。

如果你想进行深拷贝,那么你可以分配一个新数组,将新指针指向这个单独的分配,然后从旧数组中复制字符串。

但这不一定是您应该编写类的方式。您应该做的是根据用例使用 std::string 成员或 std::vector<char>


<块引用>

一个字符串甚至包含 \0 之类的字符,这样我就无法使用 string 类型。

不清楚您的意思。如果您试图说 std::string 不能包含空终止符,那么您就错了。


附言避免在 C++ 中使用 malloc