www.digitalmars.com [Home] [Search] [D]

Last update Jan 24, 2002


Programming in D for C++ Programmers

Every experienced C++ programmer accumulates a series of idioms and techniques which become second nature. Sometimes, when learning a new language, those idioms can be so comfortable it's hard to see how to do the equivalent in the new language. So here's a collection of common C++ techniques, and how to do the corresponding task in D.

See also: Programming in D for C Programmers


Defining constructors

The C++ Way

Constructors have the same name as the class:
	class Foo
	{
		Foo(int x);
	};
	

The D Way

Constructors are defined with the this keyword:
	class Foo
	{
		this(int x) { }
	}
	
which reflects how they are used in D.

Base class initialization

The C++ Way

Base constructors are called using the base initializer syntax.
	class A { A() {... } };
	class B : A
	{
	     B(int x)
		: A()		// call base constructor
	     {	...
	     }
	};
	

The D Way

The base class constructor is called with the super syntax:
	class A { this() { ... } }
	class B : A
	{
	     this(int x)
	     {	...
		super();		// call base constructor
		...
	     }
	}
	
It's superior to C++ in that the base constructor call can be flexibly placed anywhere in the derived constructor. D can also have one constructor call another one:
	class A
	{	int a;
		int b;
		this() { a = 7; b = foo(); }
		this(int x)
		{
		    this();
		    a = x;
		}
	}
	
Members can also be initialized to constants before the constructor is ever called, so the above example is equivalently written as:
	class A
	{	int a = 7;
		int b;
		this() { b = foo(); }
		this(int x)
		{
		    this();
		    a = x;
		}
	}
	

Comparing structs

The C++ Way

While C++ defines struct assignment in a simple, convenient manner:
	struct A x, y;
	...
	x = y;
	
it does not for struct comparisons. Hence, to compare two struct instances for equality:
	#include <string.h>

	struct A x, y;

	inline bool operator==(const A& x, const A& y)
	{
	    return (memcmp(&x, &y, sizeof(struct A)) == 0);
	}
	...
	if (x == y)
	    ...
	
Note that the operator overload must be done for every struct needing to be compared, and the implementation of that overloaded operator is free of any language help with type checking. The C++ way has an additional problem in that just inspecting the (x == y) does not give a clue what is actually happening, you have to go and find the particular overloaded operator==() that applies to verify what it really does.

There's a nasty bug lurking in the memcmp() implementation of operator==(). The layout of a struct, due to alignment, can have 'holes' in it. C++ does not guarantee those holes are assigned any values, and so two different struct instances can have the same value for each member, but compare different because the holes contain different garbage.

To address this, the operator==() can be implemented to do a memberwise compare. Unfortunately, this is unreliable because (1) if a member is added to the struct definition one may forget to add it to operator==(), and (2) floating point nan values compare unequal even if their bit patterns match.

There just is no robust solution in C++.

The D Way

D does it the obvious, straightforward way:
	A x, y;
	...
	if (x == y)
	    ...
	

Copyright (c) 1999-2002 by Digital Mars, All Rights Reserved