@@ -933,17 +933,119 @@ $(H2 $(LNAME2 packing-and-alignment, Packing and Alignment))
933
933
934
934
$(H2 $(LNAME2 lifetime-management, Lifetime Management))
935
935
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.)
947
1049
948
1050
$(H2 $(LNAME2 special-member-functions, Special Member Functions))
949
1051
0 commit comments