0

I have a pretty weak understanding of pointers in the very first place, but have had little luck finding out exactly why you need them in class definitions.

I know that pointers are a type of variable that point to the memory address of another variable. That's about where my real understanding begins and ends.

However, I can't possibly see their use in the beginning of this derived class:

class Circle : public Shape {

  private: int* radius;

  ....
  ....

}

Why would radius be a pointer? What purpose does this serve?

user3308043
  • 747
  • 2
  • 7
  • 20
  • You can change the value pointed by `radius` from outside the class. – Rikayan Bandyopadhyay Mar 16 '14 at 07:03
  • 2
    I have to assume dissection of the two lines of `....` and the followup implementation, both of which you have at your disposal and neither of which do we, may lead to at least a *some* insight as to the author's intent (including the *potential* possibility that they were/are... misguided). As presented now, you're asking us to say what the author was thinking, with sheer speculation being the only possible result. The purpose of `radius` is to point to something (duh). Beyond that, its impossible to say *why* without seeing more code. – WhozCraig Mar 16 '14 at 07:05
  • Like..personal preference? – texasbruce Mar 16 '14 at 07:05
  • If you can't think of a situation to use pointers, don't worry about it. When a situation does come up where you need a pointer, then you can use one. FWIW I can't see what the author intended to do with `radius` either. – M.M Mar 16 '14 at 07:08

3 Answers3

3

Pointers' use cases are based on fact that two objects whose pointers are referring the same memory location can communicate via that memory.

Three main purposes are:

  • The communication itself (see example below)
  • Economy: if your function needs some BigFatObject as a parameter, then you declare this parameter to have type BigFatObject*. That way you reduce stack usage from sizeof(BigFatObject) (which can be huge) to sizeof(void*) (which is typically only 4/8 bytes)
  • Decomposition big omnipotent object to the graph of much simpler object. In that case the objects that need some other objects to do their job will hold a pointer to the needed objects

For example:

class SharedObject
{
public:
  int getValue() { return value; }
  void setValue(int value) { this->value = value; }  

private:
    int value;
};

class CommunicatesThroughSharedObject
{
public:
    CommunicatesThroughSharedObject(SharedObject *shared)
    {
        this->shared = shared;
    }

private:
    SharedObject *shared;
};

SharedObject shared;
CommunicatesThroughSharedObject c1(&shared), c2(&shared);

Now you can get c1 and c2 communicating via calling their shared variable's getValue and setValue methods

Kirill Gamazkov
  • 2,948
  • 1
  • 15
  • 21
  • I'm certain I have to go read/look at some tutorials to get a better understanding of the use of pointers, but this is an absolutely clear and concise explanation, thank you. – user3308043 Mar 16 '14 at 07:32
  • The pointers are references themselves, so generally no need to pass them by reference. More strictly, if your pointer is IN parameter, you can pass it by value. If your pointer is OUT parameter (when you need to return several values from the single call), then you pass it by reference or doble-pointer (int** for example) – Kirill Gamazkov Mar 16 '14 at 07:44
  • example: void MethodWithSeveralOutput(const int *inputParam, int **output1, double **output2) { *output1 = inputParam; *output2 = new double[1]; output2[0] = *inputParam; } – Kirill Gamazkov Mar 16 '14 at 07:47
  • Can I ask you a forbidden question on SO without being slammed here? I'm coming from a c# and Java background. What is the reason for pointers? – user3308043 Mar 16 '14 at 07:52
  • Take a look at this: http://stackoverflow.com/questions/22146094/why-should-i-use-a-pointer-rather-than-the-object-itself. The reason is: in Java everything (except primitives) is actually a pointer. In C# everything (except structs and primitives) is actually a pointer too. – Kirill Gamazkov Mar 16 '14 at 07:59
  • Like, those languages seem to get along fine without them – user3308043 Mar 16 '14 at 08:18
  • Their GC is smart enough to handle most common cases. Most common, but not all. C++ gives you more fine-grained control, but at a cost of responsibility to handle memory semi-manually. – Kirill Gamazkov Mar 16 '14 at 08:52
1

Pointers allow you to take advantage of a lot of nifty language features, polymorphism and dynamic memory allocation being the most important of the top of my head. Some other techniques such as the pImpl Idiom also use pointers.

In the example above, the declaration of radius as a pointer seems counter-intuitive (indeed, one can argue that it is not necessary: it does not provide any real benefits and yet complicates things for the programmer).

However, there are cases where pointers-as-members are very useful. Consider the following case where a class representing a Person:

class Person
{
  char* _name;
  public:
      Person(const char* name);
};

Now, declaring the member name as a pointer allows you to allocate memory later, therefore you can allocate only as much memory as needed via the ctor. You can used arrays to do the same, but you'd end up wasting memory.

As a side note, the code for Person class is definitely not the proper C++ way of doing things. Using a std::string would be the way to go.

Bhargav Bhat
  • 8,939
  • 1
  • 17
  • 29
0

You would typically use a pointer to refer to a resource that Class does not own, perhaps it is shared with other circles. Pointers can also be useful for polymorphism. The pointer could point at a base class and the actual type is not decided until run time. All this could be achieved with more safety using references but pointers have the advantage of being nullable so could be used if the resource might not exist at the point that the Circle is constructed.

This does not make much sense for a radius but maybe for a logger:

#include <iostream>
#include <string>

class Logger {
public:
  virtual ~Logger() {}
  virtual void log(const std::string& message) = 0;
};

class FileLogger : public Logger {
public:  
  void log(const std::string& message) {/*...*/ }

};

class TestLogger : public Logger {
public:
  void log(const std::string& message) { std::cout << message << std::endl;}
};

class Shape {
//...   
};

class Circle : public Shape {
private:
  int    radius;
  Logger* logger;
  //...
public:
  Circle() : radius(1), logger(nullptr) {}

  void setLogger(Logger* in) {logger = in;}

  void doSomething() {
    //...
    if (logger != nullptr)
      logger->log("Did something");
  }
};

int main() {
  Circle circle;
  circle.doSomething();
  TestLogger logger;
  circle.setLogger(&logger);
  circle.doSomething();
  return 0;
}
Chris Drew
  • 14,004
  • 3
  • 30
  • 51