Hi,
Just out of curiosity: Why C++ choose a = new A
instead of a = A.new
as the way to instantiate an object? Doesn't latter seems more like more object-oriented?
Hi,
Just out of curiosity: Why C++ choose a = new A
instead of a = A.new
as the way to instantiate an object? Doesn't latter seems more like more object-oriented?
I reckon there is no reason. Its a = new a just because it was first drafted that way. In hindsight, it should probably be a = a.new();
A.new
is a static function of A
while a = new A
allocates memory and calls the object's constructor afterwards
The .
in C++ is only used for member access so the right hand side of the dot is always an object and not a type. If anything it would be more logical to do A::new()
than A.new()
.
In any case, dynamic object allocation is special as the compiler allocates memory and constructs an object in two steps and adds code to deal with exceptions in either step ensuring that memory is never leaked. Making it look like a member function call rather than a special operation could be considered as obscuring the special nature of the operation.
Actually, you can instantiate object with something like A.new
, if you add the proper method:
class A{
public: static A* instance()
{ return new A(); }
};
A *a = A::instance();
But that's not the case. Syntax is not the case either: you can distinguish ::
and .
"operations" by examining right-hand side of it.
I think the reason is memory management. In C++, unlike many other object-oriented languages, memory management is done by user. There's no default garbage collector, although the standard and non-standard libraries contain it, along with various techniques to manage memory. Therefore the programmer must see the new
operator to understand that memory allocation is involved here!
Unless having been overloaded, the use of new
operator first allocates raw memory, then calls the object constructor that builds it up within the memory allocated. Since the "raw" low-level operation is involved here, it should be a separate language operator and not just one of class methods.
I think the biggest confusion here is that new has two meanings: there's the built-in new-expression (which combines memory allocation and object creation) and then there's the overloadable operator new (which deals only with memory allocation). The first, as far as I can see, is something whose behavior you cannot change, and hence it wouldn't make sense to masquerade it as a member function. (Or it would have to be - or look like - a member function that no class can implement / override!!)
This would also lead to another inconsistency:
int* p = int.new;
C++ is not a pure OOP language in that not everything is an object.
C++ also allows the use of free functions (which is encouraged by some authors and the example set in the SC++L design), which a C++ programmer should be comfortable with. Of course, the new-expression isn't a function, but I don't see how the syntax reminding vaguely of free-function call can put anybody off in a language where free function calls are very common.
Just out of curiosity: Why C++ choose a = new A instead of a = A.new as the way to instance-lize an object? Doesn't latter seems more like more object-oriented?
Does it? That depends on how you define "object-oriented".
If you define it, the way Java did, as "everything must have syntax of the form "X.Y
", where X
is an object, and Y
is whatever you want to do with that object, then yes, you're right. This isn't object-oriented, and Java is the pinnacle of OOP programming.
But luckily, there are also a few people who feel that "object-oriented" should relate to the behavior of your objects, rather than which syntax is used on them. Essentially it should be boiled down to what the Wikipedia page says:
Object-oriented programming is a programming paradigm that uses "objects" – data structures consisting of datafields and methods together with their interactions – to design applications and computer programs. Programming techniques may include features such as information hiding, data abstraction, encapsulation, modularity, polymorphism, and inheritance
Note that it says nothing about the syntax. It doesn't say "and you must call every function by specifying an object name followed by a dot followed by the function name".
And given that definition, foo(x)
is exactly as object-oriented as x.foo()
.
All that matters is that x
is an object, that is, it consists of datafields, and a set of methods by by which it can be manipulated. In this case, foo
is obviously one of those methods, regardless of where it is defined, and regardless of which syntax is used in calling it.
C++ gurus have realized this long ago, and written articles such as this. An object's interface is not just the set of member methods (which can be called with the dot syntax). It is the set of functions which can manipulate the object. Whether they are members or friends doesn't really matter. It is object-oriented as long as the object is able to stay consistent, that is, it is able to prevent arbitrary functions from messing with it.
So, why would A.new
be more object-oriented? How would this form give you "better" objects?
One of the key goals behind OOP was to allow more reusable code.
If new
had been a member of each and every class, that would mean every class had to define its own new
operation. Whereas when it is a non-member, every class can reuse the same one. Since the functionality is the same (allocate memory, call constructor), why not put it out in the open where all classes can reuse it? (Preemptive nitpick: Of course, the same new
implementation could have been reused in this case as well, by inheriting from some common base class, or just by a bit of compiler magic. But ultimately, why bother, when we can just put the mechanism outside the class in the first place)
please read the code (it works), and then you'll have different ideas:
CObject *p = (CObject*)malloc(sizeof *p);
...
p = new(p) CObject;
p->DoSomthing();
...
Why one should have seperate new of each class ?
I dont think its needed at all because the objective of new is to allocate appropriate memory and construct the object by calling constructor. Thus behaviour of new is unique and independent irrespective of any class. So why dont make is resuable ?
You can override new when you want to do memory management by yourself ( i.e. by allocating memory pool once and returning memory on demand).