C++ vs. Objective-C : designated constructor

For last two years, not so few of Korean programmers, who just started to learn Objective-C, asked me about Objective-C due to my poor PDF document which explained about Objective-C written for members of osxdev.org.

Because the document was originally written for explaining difference between C++ and Objective-C, and it was changed to be Objective-C language guidebook, it contained many errors and I let others contribute to finishing the document. However, nobody joined the “community” work, and it remained just like it was.

Today, after giving up doing things for company work during this weekend, something like to comparing C++ and Objective-C struck my mind.

So, I would like to start it with “designated constructor”.

One thing good about OOP paradigm is its modular design and thus code-reuse. Nowadays, not so many people seem to mention “OOP”. Is it so in school also?

In terms of code reuse, there is different level of code reuse than what others usually say.
Constructors are to create and initialize an instance of a class. For a class, there can be multiple constructors with different parameters expecting some initial variables. The one which has more number of parameters will be a more specific constructor.
So, in this case, Objective-C allows designated initializer. ( In Obj-C initializer can be thought as constructor. )

- (id)init;
- (id)initWithDescription:(NSString *)description andAddress:(NSString *)address;

How they are implemented is like this.

- (id) init
	return [self initWithDescription:@"I'm a child" andAddress:@"At corner of Internet"];

- (id)initWithDescription:(NSString *)description andAddress:(NSString *)address
	self = [super initWithDescription:description];
	if( self != nil )
		NSLog(@"initializing ChildClass");
		self.address = address;

	return self;

As you can see, the init message send initWithDescription:andAddress to itself. And the initWithDescription:andAddress calls the designated message of its super class, initWithDescription.

Can you see the difference between this pattern and C++ constructor pattern?

Let’s try something similar with C++.

CBaseClass::CBaseClass( void )
	cout << "CBaseClass() constructor" << endl;

	// This will create a new instance of CBaseClass in heap, 
	// not calling another constructor.
	CBaseClass( "Bogus" );

CBaseClass::CBaseClass( std::string strWhoIam )
	cout << "CBaseClass( std::string ) constructor" << endl;
	m_strWhoIam = strWhoIam;

In its default constructor, it tried use a more specific constructor CBaseClass( std::string strWhoIam ).
However, in C++ grammer, this is not right. CBaseClass(“Bogus”) call in the default constructor is to create a new instance of a class in its stack. It doesn’t use the more specific constructor to initialize itself.

So, in this level of code reuse is not possible only with constructors.
Well, C++ is very flexible language and it is kind of “Swiss Army Knife”. It can do whatever.
If you think about how commercial frameworks solves this kind of issue, one thing will occur in your mind. Create() method!. Yes. MFC classes have bunch of Create() methods. Some others will have “Initialize()” or “SetUp()” methods. If you have overloaded member functions with different parameters under those names, you can achieve this level of code reuse.

Well, wait. I have seen lots of smart indian programmers who knew some undocumented behaviour of C++ and other languages. It is not good to use those undocumented behaviour because it can be changed any time and you can’t ensure compatibility of your codes with different C++ compilers.

So, let’s try this to see if it works.

Designated Constructor in C++?

Hmm.. it doesn’t work.

According to Objective-C compiler writers, Obj-C is just a simple extension of C with OOP in mind. However, very often I can notice that Obj-C has better OOPness than C++.
This is one example of that.

Let’s move forward.
With C++, between a parent class and a child class, you can call a specific constructor of the parent class from a constructor of the child class.

CChildClass::CChildClass( std::string strWhoIam, std::string strAddress ) : CBaseClass( strWhoIam )
	m_strAddress = strAddress;

So, by doing this, the parent class does it own chore and the child class can do its own chore.
So, you can divide the chores vertically in C++ with constructors only.

OK. Now take a look at it with other methods than constructor.
Generally if you want to hand over some chores to its parent class, you would write codes like this.

void CChildClass::Test2( void )
	cout << "\tCChildClass::Test2() called" << endl;

Because Test2() or CBaseClass is overridden, you should call it explicitly if you want let the super class method do something for the child class.

In the case of Objective-C, you would just send the same message to super.

- (void)test
	[super test];
	NSString *address = self.address;
	NSString *whoIam = self.whoIam;
	NSLog(@"address : %@, whoIam : %@", address, whoIam );

Can you see the difference? In Objective-C, you don’t need to know how a super class is named. if you send message to super, it will go one level up to its super class.
( “super” class is “parent” class. “super” is used in languages driven from SmallTalk, while “parent” seems to be used in languages driven from Simula” )

There will be good and bad side for the two approaches, but I think that Objective-C approach is better presumably. It keeps inheritance relationship in mind, while the one of C++ seems to break “data hiding” in general meaning and it looks like “discrete” codes.
“Data hiding” or “Data encapsulation” means that you, lies outside of a class, don’t need to know about the internals of the class. But in the case of C++, the child class should know its parent classe name. Also, it gives you feeling like “I can call any methods of any class”. So, it doesn’t feel like the integration between a parent class and its child class is as tight as that of Objective-C.

Download the sample projects

Leave a Reply

Please log in using one of these methods to post your comment:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google photo

You are commenting using your Google account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s

%d bloggers like this: