C ++按值传递struct或object

时间:2010-07-29 11:08:42

标签: c++ memory-management

我有这个:

enum Units { Pounds, Kilos };

struct Configuration
{
    const Units units;
    const char *name;

    inline Configuration(Units pUnits, char *pName) : units(pUnits)
    {
        name = strdup(pName);
    }

    inline ~Configuration() { free((void *)name); }
};

我将其中一个传递给这样的方法:

Configuration cc(Kilos, "abc");
cdao->write(cc);

我从这里遇到了令人讨厌的崩溃,直到我尝试重新定义方法来参考:

Configuration cc(Kilos, "abc");
cdao->write(&cc);

现在一切正常。

但是,按价值结构怎么可能与内存紧密相连?

4 个答案:

答案 0 :(得分:6)

你使用strdup的事实表明你的代码有问题,而错误的是你没有复制构造函数。每当你有一个析构函数时,你几乎肯定还需要一个复制构造函数,它会在你按值调用时正确复制对象。

改善您的代码:

  • 创建一个复制构造函数,可能是一个正确分配和复制字符串的赋值运算符

  • 更好的是,摆脱strdup - 使用std:;字符串,在这种情况下,你不需要析构函数,复制ctor或赋值操作。

  • 摆脱“内联”关键字 - 它们什么都不做。

答案 1 :(得分:2)

您没有提供自己的复制构造函数或赋值运算符。因此,当您进行复制或赋值时,将使用编译器生成的复制构造函数和赋值运算符,在这种情况下实际上并不正确。它们只是复制每个成员,因此最终会有两个配置对象引用相同的字符数组。并且两个Configuration对象都有责任删除数组,这几乎肯定会导致“双删除”错误。

请记住“rule of three”。这里的问题是指针的行为不像你想要的那样。如果您使用了std :: string作为成员,则不必编写自己的复制构造函数,析构函数,赋值运算符。那是因为编译器生成的只是调用其成员的相关操作,而string-member已经正确地处理了这个 - 与指向char的指针不同。

答案 2 :(得分:1)

当您在没有引用的情况下调用它时,它会复制units*name,但不会复制*name内的值。因此,当该临时对象被破坏时,它会从*name的所有实例中释放Configuration

答案 3 :(得分:1)

你必须为你的struct添加一个拷贝构造函数并处理char * name; (意思是,分配和删除内存,用值初始化)。

无论如何,对字符串使用char *是个好主意。使用std :: string,它将为你处理一切。