Related
Is it true that for C++ to work similarly in terms of modern OOP as in Java, Ruby, Python, the function (or methods) must be declared virtual and if not, what "strange" behaviors may occur?
I think it is true that for Java, Ruby, Python, and possibly other OOP languages that are late comers such as PHP and Lua, and even Smalltalk and Objective-C, all methods are just what is known as "virtual functions"?
"Method" is an unfortunately overloaded term that can mean many things. There's a reason C++ prefers different terminology, and that's because not only does it do something different from other languages, but it intends to do something different from what other languages do.
In C++ you call a member function. i.e. you externally make a call to a function associated with an object. Whether that function is virtual or not is secondary; what matters is the intended ordering of your actions - you're reaching into the object's scope, and commanding it to take a specific action. It might be that the object can specialize the action, but if so, it warned you in advance that it would do this.
In Smalltalk and the languages that imitate it (Objective-C most closely), you send a message to an object. A message is constructed on your side of the call consisting of a task name (i.e. method selector), arguments, etc., and the packed up and sent to the object, for the object to deal with as it sees fit. Semantically, it's entirely the object's decision what to do upon receipt of the message - it can examine the task name and decide which implementation to apply dynamically, according to a user-implemented choice process, or even do nothing at all. The outside calling code doesn't get to say what the object will do, and certainly doesn't get any say in which procedure actually runs.
Some languages fall in the middle ground, e.g. Java is inspired by the latter, but doesn't give the user any way to specify unusual dynamic responses - for the sake of simplicity every message does result in a call, but which call is still hidden from the external code, because it's entirely the object's business. C++ was never built on this philosophy of messages in the first place, so it has a different default assumption about how its member functions should operate.
The thing is that C++ is like the great grand father. It has many features, which often requires huge code definition.
Consider an example:
class A
{
virtual void fn() = 0;
};
class B: A
{
void fn();
};
#include "a.hpp"
#include "b.hpp"
int main()
{
A *a = new B();
a->fn();
}
This would implement overriding in C++.
Note that virtual void fn()=0 makes the class A abstract, and a pointer to base class (A) is essential.
In Java, the process is even simpler
abstract class A
{
abstract void fn();
}
class B extends A
{
void fn() {
//Some insane function :)
}
}
public static void main(String[] args) {
B ob = new B();
ob.fn();
}
Well, the effect is same; but the process is largely different. In short, C++ does have many features implemented in languages like Java, Ruby etc. but it is simply implemented using some (often complicated) techniques.
Regarding Php, since it is directly based on C++, there exists some syntax similarities between C++ and Php.
It is true that (for example) in Java all methods are virtual by default. In C++ it is possible to overload a non-virtual function (as opposed to overriding a virtual function) in a subclass, leading to possible counter-intutive behaviour, when only the base function is actually executed via a pointer or reference to the base class (i.e. when polymorphic behavior would normally be expected).
Because C++ is a value-based (as opposed to reference-based) language, then even when a function has been declared as virtual, the well known
object slicing problem can still arise: the superclass method is invoked when the type of a value object of a subclass is `cut down' to that of the base class (e.g. when the subclass is passed to a function which takes a base class argument by value).
For this reason, it is recommended to make all non-leaf classes abstract, something which is often achieved by providing a virtual destructor, even if such would otherwise be gratuitous.
I'm reading about constructors,
When an object is instantiated for a class, c'tors (if explicitly written or a default one) are the starting points for execution. My doubts are
is a c'tor more like the main() in
C
Yes i understand the point that you
can set all the default values using
c'tor. I can also emulate the behavior
by writing a custom method. Then why a c'tor?
Example:
//The code below is written in C#.
public class Manipulate
{
public static int Main(string[] args) {
Provide provide = new Provide();
provide.Number(8);
provide.Square();
Console.ReadKey();
return 0;
}
}
public class Provide {
uint num;
public void Number(uint number)
{
num = number;
}
public void Square()
{
num *= num;
Console.WriteLine("{0}", num);
}
}
Am learning to program independently, so I'm depending on programming communities, can you also suggest me a good OOP's resource to get a better understanding. If am off topic please excuse me.
Head First OOA&D will be a good start.
Dont you feel calling a function for setting each and every member variable of your class is a bit overhead.
With a constructor you can initialize all your member variables at one go. Isnt this reason enough for you to have constructors.
Constructor and Destructor functionality may be emulated using regular methods. However, what makes those two type of methods unique is that the language treats them in a special way.
They are automatically called when an object is created or destroyed. This presents a uniform means to handle the most delicate operations that must take place during those two critical periods of an object's lifetime. It takes out the possibility of an end user of a class forgetting to call those at the appropriate times.
Furthermore, advanced OO features such as inheritance require that uniformity to even work.
First of all, most answers will depend at least a bit on the language you're using. Reasons that make great sense in one language don't necessarily have direct analogs in other languages. Just for example, in C++ there are quite a few situations where temporary objects are created automatically. The ctor is invoked as part of that process, but for most practical purposes it's impossible to explicitly invoke other member functions in the process. That doesn't necessarily apply to other OO languages though -- some won't create temporary objects implicitly at all.
Generally you should do all your initialization in the constructor. The constructor is the first thing called when an instance of your class is created, so you should setup any defaults here.
I think a good way to learn is comparing OOP between languages, it's like seeing the same picture from diferent angles.
Googling a while:
java (I prefer this, it's simple and full)- http://java.sun.com/docs/books/tutorial/java/concepts/
python - http://www.devshed.com/c/a/Python/Object-Oriented-Programming-With-Python-part-1/
c# - http://cplus.about.com/od/learnc/ss/csharpclasses.htm
Why constructors?
The main diference between a simple function (that also could have functions inside) and an Object, is the way that an Object can be hosted inside a "variable", with all it functions inside, and that also can react completly diferent to an other "variable" with the same kind of "object" inside. The way to make them have the same structure with diferent behaviours depends on the arguments you gave to the class.
So here's a lazy example:
car() is now a class.
c1 = car()
c2 = car()
¿c1 is exactly c2? Yes.
c1 = car(volkswagen)
c2 = car(lamborghini)
C1 has the same functionalities than C2, but they are completly diferent kinds of car()
Variables volkswagen and lamborghini were passed directly to the constructor.
Why a -constructor-? why not any other function? The answer is: order.
That's my best shot, man, for this late hours. I hope i've helped somehow.
You can't emulate the constructor in a custom method as the custom method is not called when the object is created. Only the constructor is called. Well, of course you can then call your custom method after you create the object, but this is not convention and other people using your object will not know to do this.
A constructor is just a convention that is agreed upon as a way to setup your object once it is created.
One of the reasons we need constructor is 'encapsulation',the code do something initialization must invisible
You also can't force the passing of variables without using a constructor. If you only want to instantiate an object if you have say an int to pass to it, you can set the default constructor as private, and make your constructor take an int. This way, it's impossible to create an object of that class without having it take an int.
Sub-objects will be initialized in the constructor. In languages like C++, where sub-objects exist within the containing object (instead of as separate objects connected via pointers or handles), the constructor is your only chance to pass parameters to sub-object constructors. Even in Java and C#, any base class is directly contained, so parameters to its constructor must be provided by your constructor.
Lastly, any constant (or in C#, readonly) member variables can only be set from the constructor. Even helper functions called from the constructor are unable to change them.
Most likely an OO concept question/situation:
I have a library that I use in my program with source files available. I've realized I need to tailor the library to my needs, say I need to modify the behavior of a single functions F in class C, while leaving the original library's source intact, to be able to painlessly upgrade it when needed.
I realize I can make my own class C1 inherited from C, place it in my source tree, and write the function F how I see it fit, replacing all occurrences of
myObj = new C();
with
myObj = new C1();
throughout my code.
What is the 'proper' way of doing this? I suspect the inheritance method I described has problems, as the library in its internals would still use C::F instead of my C1::F, and it would be way cooler if I could still refer to C::F not some strange C1::F in my code.
For those that care - the language is PHP5, and I'm kinda OOP newbie :)
I think subclassing is pretty much the best way to add functionality to an external library.
The alternative is the decorator pattern whereby you have to wrap every method of the C class. (There is a time and place for the decorator pattern, but I think this isn't it)
You say:
as the library in its internals would still use C::F instead of my C1::F
Not necessarily true. If you pass an instance of the C1 class to a library function, then any calls to method F of that object would still go through your C1::F method. The same also happens when the C class accesses its own method by calling $this->F() -- because it's still a C1 object. This property is called polymorphism
Of course this does not apply when the library's code itself instantiates a new object of class C.
When I first started working with object-oriented programming languages, I was taught the following rule:
When declaring a field in a class, don't initialize it yet. Do that in the constructor.
An example in C#:
public class Test
{
private List<String> l;
public Test()
{
l = new List<String>();
}
}
But when someone recently asked me why to do that, I couldn't come up with a reason.
I'm not really familiar with the internal workings of C# (or other programming languages, for that matter, as I believe this can be done in all OO languages).
So why is this done? Is it security? Properties?
If you have multiple constructors, you might want to initialize a field to different values
When you initialize the field in the constructor, there can be no confusion over when exactly it is initialized in regard to the rest of the constructor. This may seem trivial with a single class, but not so much when you have an inheritance hierarchy with constructor code running at each level and accessing superclass fields.
The C# compiler will take any non-static member intialization that you do inline and move it into the constructor for you. In other words this:
class Test
{
Object o = new Object();
}
gets compiled to this:
class Test
{
Object o;
public Test()
{
this.o = new Object();
}
}
I am not sure how compilers for other languages handle this but as far as C# is concerned it is a matter of style and you are free to do whichever you wish. Please note that static fields are handled differently: read this article for more information on that.
One reason to do it is that it puts all of the initialization code in one place which is convenient for others reading your class. Having said this I don't really do it for two primary reasons. (1) I use TDD/Unit testing to define the behavior of my class. If you want to know what the parameterless constructor does, you should really read the tests I've built on the parameterless constructor. (2) With C# 3.0, I typically use automatic properties and inline initialization with a parameterless constructor to instantiate the object. This is much more flexible and it puts the definition of the properties right in line where the code is being used. This would override any initialization in the constructor so I rarely put any there. Of course, this only applies to C#.
Ex. (of 2)
var foo = new Foo { Bar = "baz" };
public class Foo
{
public string Bar { get; set; }
public Foo() { }
}
sometimes the constructor has parameters that are used for initializing internal variables. For example size of arrays
I haven't heard a compelling reason to not offer both options. I suspect that the real reason has to do with simplifying the language structure from a parsing perspective. This is especially true in C-derivative languages where parsing an assignment statement requires 75% of the language syntax rules. It seems to me that allowing it and defining how it would work precisely would be nice. I agree with Michael's comment about the complexity increase as you insert inheritance and multiple constructors but just because you add a feature doesn't mean that you have to use it. I would vote to support both even though my vote doesn't really add up to much.
I always like to think of the class as a factory for objects, and the constructor as the final stop on the production line. The fields declared in the class are blueprints descirbing the object, but the blueprint won't be realised into an object before such an object is ordered tthrough a call to the constructor... Also, as someone pointed out, doing all your initialisations in your constructor will improve readability, as well as it wil provide for dynamicity in initialisation (it might not be a parameterless constructor you're dealing with).
Also, in some languages the constructor may be used for resetting an object to an original state, which is why it will then be necessary to instatiate the object in the constructor.
When programming C++ we used to create copy constructors when needed (or so we were taught). When switching to Java a few years ago, I noticed that the Cloneable interface is now being used instead. C# followed the same route defining the ICloneable interface. It seems to me that cloning is part of the definition of OOP. But I wonder, why were these interfaces created, and the copy constructor seems to have been dropped?
When I thought about it, I came to the thought that a copy constructor would not be useful if one needs to make a copy of an object whose type is not known (as in having a reference to a base type). This seems logical. But I wonder whether there are other reasons that I do not know of, for which the Cloneable interfaces have been favored over copy constructors?
I think it's because there is no such inherent need for a copy constructor in Java and in C# for reference types. In C++ objects are named. You can (and you will most often) copy (and in C++1x move) them around e.g when returning from functions, since returning pointers require you to allocate dynamic memory which would be slow and painful to manage. The syntax is T(x) so it makes sense to make a constructor taking a T reference. C++ couldn't make a clone function, since that would require returning an object by value again (and thus another copy).
But in Java, objects are unnamed. There are only references to them, which can be copied, but the object itself isn't copied. For the cases when you actually need to copy them, you can use the clone call (but i read in other anwers clone is flawed. i'm no java programmer so i cannot comment that). Since not the object itself is returned, but rather a reference to it, a clone function will suffice. Also a clone function can be overriden. That's not going to work with copy constructors. And incidentally, in C++ when you need to copy a polymorphic object, a clone function is required too. It's got a name, the so-called virtual copy constructor.
Because C++ and Java (and C#) aren't the same thing. C++ has no built-in interfaces because interfaces aren't part of the language. You can fake them with abstract classes but they aren't how you think about C++. Also, in C++ assignment is normally deep.
In Java and C# assignment just involves copying the handle to the internal object. Basically when you see:
SomeClass x = new SomeClass();
in Java or C#, there's a level of indirection builtin that doesn't exist in C++. In C++, you write:
SomeClass* x = new SomeClass();
Assignment in C++ involves the dereferenced value:
*x = *another_x;
In Java you can get access to the "real" object as there is no dereference operator like *x. So to do a deep copy, you need a function: clone(). And both Java and C# wrapped that function into an interface.
It's the issues of final type and of cascading the clone operation through the super classes which is not addressed by copy constructors - they are not extensible. But the Java clone mechanism is widely considered badly broken too; especially problems where a subclass does not implement clone(), but inherits from a superclass that implements cloneable.
I strongly recommend you research cloning carefully, whatever path you choose - you will likely choose the clone() option, but make sure you know exactly how to do it properly. It's rather like equals() and hashCode() - looks simple on the surface, but it has to be done exactly right.
I think you haven't get the right point. I give you my two cents.
Fundamentally there's a problem: creating a clone of a class without knowing the exact class type. If you use copy constructor, you cannot.
Here is an example:
class A {
public A(A c) { aMember = c.aMember }
int aMember;
}
class B : A {
public B(B c) : base(c) { bMember = c.bMember }
int bMember;
}
class GenericContainer {
public GenericContainer(GenericContainer c) {
// XXX Wrong code: if aBaseClass is an instance of B, the cloned member won't
// be a B instance!
aBaseClass = new A(c.aBaseClass);
}
A aBaseClass;
}
The Clone method, if declare virtual, could create the right class instance of the generic member.
An this problem is common to every language, C# C++ or Java...
Maybe this is what you was meaning, but I cannot understand this from any answer.
Just wanted to add that in Java the copy constructor is not completely useless.
There are cases where your class has a private instance variable of a mutable non-final type, e.g. Date, and has a setter and getter for the variable. In the setter, you should make a copy of the given date, because the caller could modify it later and thereby manipulate your object's internal state (usually by accident, but maybe intentional). In the getter, the same precaution is required.
The defensive copy could be implemented by calling clone() (the class Date is cloneable), but a malicious caller could call the setter with a subclass of Date which overrides the clone() method with {return this;}, and so the caller might still be able to manipulate your object. This is where the copy constructor comes into play: By calling new Date(theDate), you are sure to get a fresh Date instance with the same timestamp as the given date, without any connection between the two date instances. In the getter, you could use the clone method, because you know the private variable will be of class Date, but for consistency, usually the copy constructor is used there, too.
Also note that the copy constructor would note be required if the Date class was final (calling clone() were safe) or immutable (no copy required).
I think its only because once u have defined a copy constructor, you could never pass the reference itself again. (Unless it would have a function that does that...but thats not any easier than using the clone() method.)
In C++ its not a problem: you can pass the whole object or its reference.