@@ -939,17 +939,124 @@ $(H2 $(LNAME2 packing-and-alignment, Packing and Alignment))
939939
940940$(H2 $(LNAME2 lifetime-management, Lifetime Management))
941941
942- $(P C++ constructors, copy constructors, move constructors and destructors
943- cannot be called directly in D code, and D constructors, postblit operators
944- and destructors cannot be directly exported to C++ code. Interoperation of
945- types with these special operators is possible by either 1$(RPAREN)
946- disabling the operator in the client language and only using it in the host
947- language, or 2$(RPAREN) faithfully reimplementing the operator in the
948- client language. With the latter approach, care needs to be taken to ensure
949- observable semantics remain the same with both implementations, which can be
950- difficult, or in some edge cases impossible, due to differences in how the
951- operators work in the two languages. For example, in D all objects are
952- movable and there is no move constructor.)
942+ $(P C++ constructors, copy constructors, and destructors can be called directly in D code.
943+ C++ move constructors cannot be called directly in D code.
944+ )
945+
946+ $(P In a foo.cpp file: )
947+
948+ $(CPPLISTING
949+ #include $(LT)iostream$(GT)
950+
951+ using namespace std;
952+
953+ class A
954+ {
955+ public:
956+ A(int i);
957+ ~A();
958+ };
959+
960+ A::A(int i)
961+ {
962+ cout << "calling C++ integer constructor " << endl;
963+ }
964+
965+ A::~A()
966+ {
967+ cout << "calling C++ destructor " << endl;
968+ }
969+ )
970+
971+ $(P In a bar.d file: )
972+
973+ ------
974+ extern(C++) class A
975+ {
976+ this(int i);
977+ ~this();
978+ }
979+
980+ void main()
981+ {
982+ auto obj1 = new A(5); // calls the constructor
983+ destroy!false(obj1); //calls the destructor
984+ }
985+ ------
986+
987+ $(P Compiling, linking, and running produces the output:)
988+
989+ $(CONSOLE
990+ $(GT) g++ -c foo.cpp
991+ $(GT) dmd bar.d foo.o -L-lstdc++ && ./bar
992+ calling C++ integer constructor
993+ calling C++ destructor
994+ )
995+
996+ $(P Note that the C++ Copy constructor cannot be called using D classes since classes in D are reference types.
997+ Value semantics are needed to be able to copy, so use a D struct.)
998+
999+ $(P In a foo.cpp file: )
1000+
1001+ $(CPPLISTING
1002+ #include $(LT)iostream$(GT)
1003+
1004+ using namespace std;
1005+
1006+ class A
1007+ {
1008+ public:
1009+ A(int i);
1010+ A(A const& other);
1011+ ~A();
1012+ };
1013+
1014+ A::A(int i)
1015+ {
1016+ cout << "calling C++ integer constructor" << endl;
1017+ }
1018+
1019+ A::A(A const& other)
1020+ {
1021+ cout << "calling C++ copy constructor" << endl;
1022+ }
1023+
1024+ A::~A()
1025+ {
1026+ cout << "calling C++ destructor" << endl;
1027+ }
1028+ )
1029+
1030+ $(P In a bar.d file: )
1031+
1032+ ------
1033+ extern(C++, class) struct A
1034+ {
1035+ this(int i);
1036+ this(ref const A other);
1037+ ~this();
1038+ }
1039+
1040+ void main()
1041+ {
1042+ A obj1 = 6; // calls the integer constructor
1043+ auto obj2 = A(obj1); // calls the copy constructor
1044+ }
1045+ ------
1046+
1047+ $(P Compiling, linking, and running produces the output:)
1048+
1049+ $(CONSOLE
1050+ $(GT) g++ -c foo.cpp
1051+ $(GT) dmd bar.d foo.o -L-lstdc++ && ./bar
1052+ calling C++ integer constructor
1053+ calling C++ copy constructor
1054+ calling C++ destructor
1055+ calling C++ destructor
1056+ )
1057+
1058+ $(P Notice there's no need to call destroy on a struct object to invoke the destructor
1059+ since it does stack allocation(by default) and its lifetime ends with its declaration scope.)
9531060
9541061$(H2 $(LNAME2 special-member-functions, Special Member Functions))
9551062
0 commit comments