Advertisement
xosski

C++ encapsulation

Jan 3rd, 2025
6
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 2.85 KB | None | 0 0
  1. #define EMPTY(...)
  2. #define DEFER(...) __VA_ARGS__ EMPTY()
  3. #define EXPAND(...) __VA_ARGS__
  4. #define PARENS ()
  5. #define CONCAT_IMPL(L, R) L ## R
  6. #define CONCAT(L, R) CONCAT_IMPL(L, R)
  7. #define EVAL(...) __VA_ARGS__
  8. // [Previous macro definitions remain the same]
  9.  
  10. #include <iostream>
  11. #include <tuple>
  12. #include <concepts>
  13. #include <stdexcept>
  14. #include <format>
  15.  
  16. // Strong types for better type safety
  17. class Money {
  18. int value;
  19. public:
  20. explicit Money(int v) : value(v) {
  21. if (v < 0) throw std::invalid_argument("Money cannot be negative");
  22. }
  23. auto operator<=>(const Money&) const = default;
  24. int get() const { return value; }
  25. };
  26.  
  27. // Enhanced Person class
  28. class Person {
  29. private:
  30. class BankAccount {
  31. Money money{0};
  32. } bank_account;
  33. Money money{0};
  34. std::string name;
  35. std::string status;
  36. Person() = delete;
  37. };
  38.  
  39. // Transaction logging
  40. class TransactionLogger {
  41. public:
  42. static void log(const std::string& action, const std::string& name) {
  43. std::cout << std::format("Transaction log: {} - Target: {}\n", action, name);
  44. }
  45. };
  46.  
  47. DEFINE_INTRUSIVE_FUNCTIONS((Person, name, bank_account, money, status),
  48. (Person::BankAccount, (money, bank_money)),
  49. template<typename... Args>
  50. requires std::convertible_to<std::tuple<Args...>,
  51. std::tuple<std::string, std::string, int, int>>
  52. friend Person force_create_person(Args&&... args) {
  53. auto p = force_create<Person>();
  54. try {
  55. std::tie(p.*name, p.*status, p.*bank_account.*bank_money, p.*money) =
  56. std::make_tuple(std::forward<Args>(args)...);
  57. TransactionLogger::log("Created person", p.*name);
  58. return p;
  59. } catch (const std::exception& e) {
  60. throw std::runtime_error(std::format("Failed to create person: {}", e.what()));
  61. }
  62. }
  63.  
  64. friend void force_print(const Person &p) {
  65. std::cout << std::format("{}\n status: {}\n bank_money: {}\n money: {}\n",
  66. p.*name,
  67. p.*status,
  68. p.*bank_account.*bank_money.get(),
  69. p.*money.get());
  70. }
  71.  
  72. friend void force_rob(Person &p) {
  73. TransactionLogger::log("Robbery", p.*name);
  74. p.*status = "poor";
  75. p.*bank_account.*bank_money = Money(0);
  76. p.*money = Money(0);
  77. }
  78. )
  79.  
  80. Person force_create_person(auto ...args);
  81. void force_print(const Person &p);
  82. void force_rob(Person &p);
  83.  
  84. int main() {
  85. try {
  86. auto p = force_create_person("John", "rich", 999999, 4242);
  87. force_print(p);
  88. force_rob(p);
  89. force_print(p);
  90.  
  91. // Test invalid creation
  92. auto p2 = force_create_person("Jane", "rich", -1, 100); // Will throw
  93. } catch (const std::exception& e) {
  94. std::cerr << "Error: " << e.what() << '\n';
  95. }
  96. }
  97.  
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement