@@ -939,17 +939,124 @@ $(H2 $(LNAME2 packing-and-alignment, Packing and Alignment))
939
939
940
940
$(H2 $(LNAME2 lifetime-management, Lifetime Management))
941
941
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.)
953
1060
954
1061
$(H2 $(LNAME2 special-member-functions, Special Member Functions))
955
1062
0 commit comments