5

I come to c++ from c# and I don't understand what dynamic object is. So imagine you have class A and to create object like A *a = new A() is Normal but what is object a? It's the same thing like an array or what? We can write like a[0] or a[1]? But what going on if we overload operator [] and want to create dynamic object if we have data there and want to get data normally?

icegas
  • 71
  • 1
  • 1
  • 9
  • 1
    `a` is a pointer that holds the address of a dynamically allocated instance of class `A`. In general you don't need to use `new` to create new instances (and should avoid that like the plague). – πάντα ῥεῖ Jun 21 '17 at 14:11
  • For starters I think it is better if you understand stack vs heap memory allocation of C++. Which you can find in the following link. http://www.learncpp.com/cpp-tutorial/79-the-stack-and-the-heap/ – Will_Panda Jun 21 '17 at 14:13
  • 1
    Overloading operator[] on a class has nothing to do with using [] on a raw pointer. If you want to invoke the class' operator[] then you'd have to first dereference the pointer. – jschultz410 Jun 21 '17 at 14:28
  • There isn't much of a difference between A \*a = new A; and A \*a = new A[1]; The differences, I *think*, are that in the latter version you need to call delete [] on it and you can probably only invoke the default constructor of the type. – jschultz410 Jun 21 '17 at 14:36

3 Answers3

7

A pointer is just about what it sounds like, it's something which points somewhere else.

Take your example

A* a = new A;

That declares the variable a as a pointer. It points to an instance (an object) of the A class.

Somewhat graphically it can be seen as

+---+      +---------------+
| a | ---> | instance of A |
+---+      +---------------+

In C# (and Java) this is basically the only way to create instances of classes. All variables are (a little simplified) pointers.

In C++ you have other alternatives as well:

A a;

The definition above says that the variable a is an instance of the A class. It's not a reference, it's not a pointers, it is an A object.

Now for another difference between the two above definitions: In the first case the instance of A is created at run-time. The memory is allocated for the instance when the program is running. In the second case, the space for the instance is allocated by the compiler, at the time of compilation. However in both cases the constructor is called at run-time.

Some programmer dude
  • 400,186
  • 35
  • 402
  • 621
  • This is a great answer! I would suggest adding a bit addressing the confusion between pointers and arrays. It seems like a significant part of the question to me. – François Andrieux Jun 21 '17 at 14:15
  • I'm sorry, maybe you don't understand my question. I mean how dynamic object is represented? Is it an array? And if we create object like that A *a = new A(); can we write like that a[1]->data = 0;? – icegas Jun 21 '17 at 14:20
  • It's not an array. It's a single instance. If it were an array, how many elements would you expect it to contain? Arrays do not expand automatically when you access elements out of bounds. – François Andrieux Jun 21 '17 at 14:22
  • Your comment about run-time versus static (compiler) allocation is a bit off. If I declare a variable inside a function it is allocated at run time when that object's scope is entered. Only if an object is global (or namespace) or static of various stripes is it allocated statically by the compiler. – jschultz410 Jun 21 '17 at 14:24
4

If you write A * a = new A() the default constructor of the class A is called and it dynamically allocates memory for one object of the class A and the address of the memory allocated is assigned to the pointer a. So a points an object of the class A and not an array. However, if you want an array of A objects dynamically, then you'll have to write something like this A * a = new A[10]. This will allocate memory of 10 objects of A. And you can write a[0], a[1], ... a[9] to access the objects of the array.

Now, what would happen if we overload the [] operator? If we overload [] operator, then it should mean that the class A has some sort of array inside, and by writing a[1], where a is an object of class A, we want to get the element situated at second index. (Speaking generally, you can mean anything else using the subscript operator, but you should try to stick to the original meaning of the subscript operator). But we cannot invoke [] operator on pointers as it would mean to dereference the pointer. So to invoke the subscript operator on a pointer of an object, we have to explicitly call the subscript operator. Like this:

A * a = new A;
cout << a->operator[](0) << endl;

It creates one object of the class A, and writing a->operator[](0). It explicitly calls the overloaded subscript operator. What if we create an array dynamically?

A * a = new A[6];
cout << a[0][0] << endl;

The first subscript operator is for getting the first object in the array of objects. The second subscript operator is calling the overloaded subscript operator of the object a[0]

EDIT: I was wrong about invoking subscript operator of a class A. Thanks to jschultz410, who corrected me.

  • 1
    "It creates one object of the class A, and writing a[0] it gives the first element of the inside array, or maybe something else which the subscript operator was overloaded to mean." This isn't (typically) correct. Writing a[0] dereferences the pointer a to give a reference to the underlying class. It doesn't invoke the operator[]() on the class. Your second example looks correct. – jschultz410 Jun 21 '17 at 14:32
  • Oh. Sorry. I did not know that. I learned it now though. Thanks. Should I remove it from my answer? Although, what if I wanted to invoke operator[]() ? Will I have to call it manually like this -> `a->operator[0]` ? – Redwanul Haque Sourave Jun 21 '17 at 14:36
  • Yes, but it looks terrible. – icegas Jun 21 '17 at 14:48
  • Yes. Pretty much. I don't think there is any other way, – Redwanul Haque Sourave Jun 21 '17 at 14:51
  • Because it looks so terrible you usually wouldn’t write `a->operator[](0)` but `(*a)[0]`. It’s still not pretty, but shorter and more idiomatic. Both syntaxes do exactly the same thing. – besc Jun 21 '17 at 15:18
1

'a' is a pointer (memory address) to the memory where object 'A' is allocated. Yest it behaves as an array. However you have only one element in it, so 'a[0]' will be equivalent to '*a'. Do not try a[1] in your case. It will compile, but most likely crash at run. If you overload [], it is your problem now :-). Though you cannot overload [] on pointers.

BTW, in c# 'a' would also be a pointer (reference) to the object, not the object itself.

The biggest difference between the languages is that c++ does not manage memory allocation. So, if you said 'new', make sure that you also say 'delete' when you do not need the object any longer.

In 'c+' you can also create references instead of the pointers.

Serge
  • 11,616
  • 3
  • 18
  • 28
  • So and how to overload operator [] on pointers? For example if you use uniq_ptr? – icegas Jun 21 '17 at 14:24
  • @icegas `std::unique_ptr` is a class, not a pointer. As such, you can overload `operator []` for it just fine (and `std::unique_ptr` actually does that). You might want to read through a [good C++ book](https://stackoverflow.com/q/388242/1782465) to get a firmer grasp on basic C++ concepts and how they differ (or not) from C#. – Angew is no longer proud of SO Jun 21 '17 at 14:30
  • pointer is not an object. Most of the operators can be overloaded in objects only. There are few which can be overloaded statically, but not '[]'; If you need to overload [], you need to do in in your object. In this case you can use references as a more convenient way then pointers. or use pointers, but you will need this kind of syntax to use it: (*pointer)[index]. – Serge Jun 21 '17 at 17:12