2010-07-29 34 views
3

传递结构或对象我有这样的:C++通过值

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); 

现在一切正常。

但是,如何通过价值的结构与内存拧紧?

+0

你应该有'std :: string name'作为成员,并且根本不写任何析构函数。 – 2014-02-25 23:38:12

回答

2

您没有提供自己的拷贝构造函数或赋值运算符。所以,当你做一个副本或一个任务时,会使用编译器生成的拷贝构造函数和赋值操作符,在这种情况下实际上不会做正确的事情。他们只是复制每个成员,最终得到两个指向相同的字符数组的配置对象。并且这两个Configuration对象都认为删除数组几乎可以导致“双删除”错误。

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

+0

伟大的回答大家,我想我更喜欢这个。谢谢。 – 2010-07-29 13:37:45

6

你正在使用strdup的事实表明你的代码有问题,错误的是你没有一个拷贝构造函数。任何时候你有一个析构函数,你几乎肯定也需要一个拷贝构造函数,当你通过值调用时它会正确地复制对象。

为了提高代码:

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

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

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

+0

内联关键字在类声明的“外部”方法定义中使用时有意义,对吗? – 2010-07-29 13:30:56

+0

@German绝大多数情况下不是 - 使用内联的唯一真正原因是如果#包含多个翻译单元中的函数源。 – 2010-07-29 13:33:54

1

当您使用了引用调用它,它的复制units和​​但不是​​内的值。所以当这个临时对象遭到破坏时,它将从Configuration的所有实例中释放​​。

1

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

无论如何,使用char *作为字符串不是个好主意。使用std :: string,它会处理所有的事情。

+0

学生从底层学习语言可能没问题。如果他还有std :: string,他现在就没有理由复制构造函数。 – 2010-07-29 11:31:16

+0

也许它确定,如果他不会(现在了解它)。它可能会更好地看到你可以走得很远,而不用创建一个,然后在你真正需要它们的时候学习它们。 – 2010-07-29 11:57:38

+0

是的......我很长一段时间没有碰过C++,反正我更喜欢C语言。我以前从来没有碰到过这个问题,我想我总是通过ref传递对象(我想我现在会坚持)。 是的,我更愿意理解发生了什么,以及我应该如何使它与char *一起工作。感谢大家。 – 2010-07-29 13:36:58