1

I'm diving into C++ coming from the worlds of Objective-C and Java. Java gave me all the OOP knowledge I have and Objective-C taught me about manual memory management. While adapting to C++ is easy (the language definitely does not deserve the reputation it has) I am confused about one thing:

I can declare a property as string my_string or string *my_string. I know I need to delete the second, but what's the advantage in declaring it as a pointer?

ruipacheco
  • 15,025
  • 19
  • 82
  • 138
  • 4
    *"the language definitely does not deserve the reputation it has"* -> it will be interesting to hear your opinion again after a year or so ;-) – Jon Jan 17 '14 at 10:52
  • What do you mean by "property" exactly? In my answer I interpreted it as a member variable of a struct/class. It seems most other answers/comments interpret it as "any variable". – Richard Vock Jan 17 '14 at 11:00
  • @RichardVock - You are correct. And I accepted your answer even without reading this, which means you really got it. – ruipacheco Jan 17 '14 at 11:07

6 Answers6

1

In most situations there is no benefit at all to use the pointer variant.

One reason to use this is if you want the member to survive the destruction of the object (if you do not delete it in the destructor). However this necessity is usually enforced by bad design, so I'd try to avoid this.

Another reason (and the more probable one) is, if you want the member to optionally be undefined (that is you initialize the member to NULL/nullptr(c++11) in the constructor and each read access checks if the pointer is still NULL or actually points to a value). This way you can postpone intialization. However even in this case I'd suggest using smart pointers (std::shared_ptr in c++11 or boost::shared_ptr in c++98) or boost::optional...

Richard Vock
  • 1,286
  • 10
  • 23
1

People have answered almost completely, but I'd add this reason: while declaring a variable as a pointer is useless, it comes in handy if it's a big structure and you have to pass it as a parameter to many functions, like a recursive algorithm.

strcut sMyStruct
{
   // A lot of members
}

// Somewhere in your code
sMyStruct   foo;
RecursiveOperation( &foo );

// Somewhere else if you want foo to don't be modified.
void RecursiveOperation( const sMyStruct *pFoo )
{
}
// or...
void RecursiveOperation( sMyStruct *pFoo )
{
}

In this case, having *pFoo makes your code faster and cheaper, even if you could use & to pass the reference having some more safety but slightly less speed. Obviously I may be wrong but that's what jobmates teached me.

IssamTP
  • 2,408
  • 1
  • 25
  • 48
0

I know I need to delete the second

A pointer does not necessarily mean that any dynamically allocation is involved, at all. Therefore a pointer does not automatically need to be deleted.

What's the advantage in declaring it as a pointer?

As a rule of thumb you should always use automatic allocated memory (~ stack). If you'll ever feel the need to use dynamically allocated memory (for lack of space in the stack for example), you'll know. Dynamically allocated memory can also be used to manually control the lifetime of an object, but that's dangerous most of the time: that's why we have smart pointers like std::unique_ptr and std::shared_ptr.

In this particular case, unless you really need to have a pointer to an std::string as a reference (that can be nullptr) to a string, I can't see the purpose of it. Most std::string's implementations already store the char array dynamically.

Shoe
  • 74,840
  • 36
  • 166
  • 272
0

In C++ you can store variables on stack or on heap, when you manage pointers usually you are on the heap and you need manually memory managment.

Small objects are good for stack, large object like a very huge string is not good for stack and can cause a stackoverflow (stack is quite small, see you compiler to see stack space ).

std::string are not huge object on the stack because they internally manage the pointers on the heap. Declaring a string as a pointer means that you usually need that string to refering to something else.

What can I suggest to you is to avoid raw pointers always. Prefer std::unique_ptr or std::shared_ptr.

Elvis Dukaj
  • 7,142
  • 12
  • 43
  • 85
0

Nothing. In C++, use values instead of pointers unless required. Heck, you can get away with references instead of pointers in most cases as well (like function calls).

There really is no sense in using std::string*.

The only time A* makes sense, or is useful at all, is when there are subclasses of A which you want to assign to this base class pointer. An example, with the classical shape

#include <iostream>
#include <memory>
#include <vector>

class shape 
{
public:
  virtual ~shape() {}; // required to properly be able to delete base class pointers    
  virtual bool isRound() const = 0;
  virtual const char* name() const = 0;
};

class rectangle : public shape
{
public:
  bool isRound() const { return false; }
  const char* name() const { return "rectangle"; }
};

class circle : public shape
{
  bool isRound() const { return true; }
  const char* name() const { return "circle"; }
};

class square : public rectangle
{
  const char* name() const { return "square"; }
};

int main()
{
  std::vector<std::unique_ptr<shape>> shapes;
  shapes.emplace_back(new square());
  shapes.emplace_back(new circle());
  shapes.emplace_back(new rectangle());

  for(const auto& s : shapes)
  {
    if(s->isRound())
      std::cout << s->name() << " is round.\n";
    else
      std::cout << s->name() << " is not round.\n";
  }
}

Live demo

Here, the vector of pointers is only an example, it might be a member of a class or anything else really. Note I used std::unique_ptr<shape> instead of shape*. Learn about smart pointers. Fast.

rubenvb
  • 74,642
  • 33
  • 187
  • 332
0

You have to understand the fact the pointer is some thing that holds the address to a memory location .It can hold the address from stack as well as from heap

Simal Haneef
  • 179
  • 5