You can take D as easy bridge to learn C++, or you can take D as modern programming language and replaces the ancient Pascal or even C.
MetaClass
“Class References” in Delphi/Pascal
SuperClass = class
x: integer;
constructor Create(value: integer)
begin
x := value;
end;
end;
SubClass1 = class(SuperClass)
end;
SubClass2 = class(SuperClass)
end;
MyMetaClass = class of SuperClass;
//Assigning MetaClass of subclass,
//compiler only accept classes that derived from SuperClass
var
MC: MyMetaClass;
//Assigning
MC = SubClass1;
//Creating object
MyObj = MC.Create(10);
You can use classinfo, but is not a really like metaclass in Pascal but
it help you porting your projects
class SuperClass{
int x;
this(int value){
x = value;
}
}
class SubClass1: {
this(){
}
}
class SubClass2: {
this(){
}
}
Classinfo metaclass = SubClass.classinfo;
//Creating object
myObj = metaclass.create();
Disadvantage
You must have a default constructor to create it “this”, if no, myObj
will be null, and object not created
You can not use constructor with parameter like
myObj = metaclass.create(10);
here you can assign to “mc” any class, not like Pascal that check if it
derived from class defined
Sets
You can use Associative Arrays (AA) of your enum.
enum MyEnum (A, B, C)
bool[MyEnum] mySet;
or you can make alias for it
bool[MyEnum] MySet;
MySet mySet;
mySet = [A: true, B: true];
//or
mySet[b] = true;
//Notice "in" operator in D meant the key is exists, not meant exists and equal to true
if (b in mySet){
}
Encapsulation
Private, Protected, Public
class MyClass{
private:
...
protected:
...
public:
...
}
Override
Not like Pascal, Every method is virtual until you mark it as final.
Strings
Index
String index started from 0
you can use length to get size
int i = s.length;
concat
s = "Hello ";
s = s ~ "World";
Pos
import std.string;
p = s.indexOf(".");
Copy
You can use slicing, because string is array of char
t = Copy(s, 1, 5);
In D
//Like this
t = s[0..5];
t = s[0..$]; //to the last of string
Notice that if you make range from x to same value it will return slice of empty string
t = s[2..2]; //Return empty string in t
t = s[2..3]; //Return one char index by 2
Generics
You can use the powerfull templates, this example make it clear to understand
type
generic TList<T> = class
procedure Add(Value: T);
end;
...
Type
TIntegerList = specialize TList<Integer>;
TStringList = specialize TList<string>;
In D language
class List(T){
void add(T t){
//adding t
}
}
class StringList: List!string{
}
IFDEF
debug, release, version(windows)
debug{
...
}
release{
...
}
debug writeln("Hello debug world");
version(windows){
//only for windows platform
}
You can define it also like this example
import std.stdio;
debug(everything)
{
debug = level1;
debug = level2;
version = beta;
}
void main()
{
debug(level1) writeln("level1...");
debug(level2) writeln("level2...");
version(beta) writeln("it is beta version");
}
And you can use “static if” to check condition at compile time, and stop the compilation useing “static assert”
struct MyType(T)
{
static if (is (T == float)) {
static assert(false, "float type is not supported");
}
}
ref:http://ddili.org/ders/d.en/cond_comp.html
Helper
You dont need add help of class, just add global functions with paramter type of your class as first parameter.
class MyClass{
}
void doSomething(MyClass obj, int x){
}
Usage:
MyClass obj = new MyClass;
obj.doSomething(10);
Note: You can not access private or protected members on MyClass.