简体   繁体   中英

Parameter-passing of C++ objects with dynamically allocated memory

I'm new to the C++ world, but I have some experience with C and read some tutorials about C++. Now, creating objects in C++ seems quite easy and works well for me as long as the class has only attributes that are values (not pointers).

Now, when I try to create objects which allocate memory in the constructor for some of their attributes, I figure out how exactly such objects are passed between functions. A simple example of such class would be:

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

I want to use the class and pass it by value to other functions, etc. At least these examples must work without creating memory leaks or double free errors.

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

The class A is incomplete because I should override operator= and A(A& oldValue) to solve some of these problems. As I understand it, the default implementation of these methods just copy the value of the members which is causing the destructor to be called twice on the same pointer values.

Am I right and what else am I missing? In addition, do you know any good tutorial that explains this issue?

When you pass an object like that, you will create a copy of the object. To avoid doing that, you should pass a const reference...

void f2(A const & a)
{
}

This does mean that you are not allowed to change 'a' in your function - but, to be honest, you shouldn't be doing that anyways, as any changes won't be reflected back to the original parameter that was passed in. So, here the compiler is helping you out, but not compiling when you would have made a hard to find error.

Use containers and smart pointers.

Eg std::vector for dynamic length array, or boost::shared_ptr for dynamically allocated single object.

Don't deal directly with object lifetime management.

Cheers & hth.,

Specifically, you must implement a copy constructor that properly copies the memory pointer for the a variable. Any default constructor would simply copy the memory location for the a variable, which would obviously be subject to a double-delete.

Even doing this:

A value(5);
  // ...
  return value;

won't work because when A falls out of scope (at the end of the section) the delete operator for A will be called, thus deleting the a sub-variable and making the memory invalid.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM