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