我是C ++世界的新手,但我对C有一些经验并阅读了一些关于C ++的教程。 现在,使用C ++创建对象看起来非常简单,只要该类只有值(而不是指针)的属性,对我来说效果很好。
现在,当我尝试创建在构造函数中为其某些属性分配内存的对象时,我会弄清楚这些对象在函数之间是如何传递的。 这类课程的一个简单例子是:
class A {
int *a;
public:
A(int value) {
this->a = new int;
*(this->a) = value;
}
~A() {
delete this->a;
}
int getValue() const { return this->a; }
}
我想使用该类并将其通过值传递给其他函数等。至少这些示例必须在不产生内存泄漏或双重自由错误的情况下工作。
A f1() {
// some function that returns A
A value(5);
// ...
return value;
}
void f2(A a) {
// takes A as a parameter
// ...
}
A a = f1();
A b = a;
f2(a);
f2(f1());
课程A
不完整,因为我应该覆盖operator=
和A(A& oldValue)
来解决其中的一些问题。
据我了解,这些方法的默认实现只是复制成员的值,导致析构函数在相同的指针值上被调用两次。
我是对的,我还缺少什么? 另外,你知道任何解释这个问题的好教程吗?
答案 0 :(得分:2)
当您传递这样的对象时,您将创建该对象的副本。为避免这样做,您应该传递一个const引用...
void f2(A const & a)
{
}
这确实意味着您不允许在您的功能中更改“a” - 但是,说实话,您不应该这样做,因为任何更改都不会反映回原来的参数传入。所以,这里的编译器正在帮助你,但是当你很难找到错误时,编译器就不会编译。
答案 1 :(得分:2)
使用容器和智能指针。
E.g。动态长度数组为std::vector
,动态分配单个对象为boost::shared_ptr
。
不要直接处理对象生存期管理。
干杯&第h。,
答案 2 :(得分:1)
具体来说,必须实现一个复制构造函数,该构造函数正确复制 a 变量的内存指针。任何默认构造函数都只是复制 a 变量的内存位置,这显然会受到双重删除。
即使这样做:
A value(5); // ... return value;
将无效,因为当A超出范围时(在该部分的末尾),将调用A的删除操作符,从而删除 a 子变量并使内存无效