--sas

task4

May 18th, 2019
197
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 2.58 KB | None | 0 0
  1. //// main.cpp ////////
  2.  
  3. #include "storage.h"
  4.  
  5. #include <iostream>
  6. #include <string>
  7.  
  8. using namespace std;
  9.  
  10. int main() {
  11.     int i = 33;
  12.  
  13.     // With int it works very well, holding actual value:
  14.     Storage<int> st_int(i);
  15.     cout << "Stored int " << st_int.GetVal() << endl;
  16.     cout << "New val: ";
  17.     cin >> i;
  18.     st_int.SetVal(i);
  19.     cout << "Stored int " << st_int.GetVal() << endl;
  20.  
  21.     // But with usual char* it doesn't work:
  22.     char str[100] = "Hello";
  23.     Storage<char*> st_str(str);
  24.     cout << "Stored str " << st_str.GetVal() << endl;
  25.     str[1] = 'X';
  26.     // Value in storage broken:
  27.     cout << "Stored str " << st_str.GetVal() << endl;
  28.  
  29.     return 0;
  30. }
  31.  
  32. //// storage.h ////////
  33.  
  34. #pragma once
  35.  
  36. #include <cstring>
  37.  
  38. using namespace std; // в таком простом случае эта команда в .h-файле никаких проблем не вызовет
  39.  
  40. template <typename T>
  41. class Storage {
  42. public:
  43.     Storage() = default;
  44.     Storage(const T &val) : m_val(val) {};
  45.     ~Storage() = default;
  46.  
  47.     void SetVal(const T &val) {m_val = val;}
  48.     T GetVal() const {return m_val;}
  49.  
  50. private:
  51.     T m_val;
  52. };
  53.  
  54. template < >
  55. class Storage <char*> {
  56. public:
  57.     Storage() : m_val(nullptr) {}
  58.     Storage(const char* val);
  59.     ~Storage();
  60.  
  61.     void SetVal(const char* val);
  62.     char* GetVal() const;
  63.  
  64. private:
  65.     char* m_val;
  66. };
  67.  
  68. Storage<char*>::Storage(const char* val) :
  69.     m_val([val] () {
  70.         char* m_val_ = new char[strlen(val) + 1];
  71.         strcpy(m_val_, val);
  72.         return m_val_;
  73.     } ()) {};
  74.  
  75. Storage<char*>::~Storage() {
  76.     delete[] m_val; //проверка m_val != nullptr не нужна, т.к. обработка случая delete для nullptr уже зашита в nullptr и delete в этом случае не имеет никакого эффекта
  77. }
  78.  
  79. void Storage<char*>::SetVal(const char* val) {
  80.     delete[] m_val;
  81.     m_val = new char[strlen(val) + 1];
  82.     strcpy(m_val, val);
  83. }
  84.  
  85. char* Storage<char*>::GetVal() const {
  86.     if (m_val == nullptr)
  87.         return nullptr; // в случае чего, все необходимые exception будут кинуты при обращении к строке-результату вызова функции
  88.     char* res = new char[strlen(m_val) + 1];
  89.     strcpy(res, m_val);
  90.     return res;
  91. }
  92.  
  93. // На самом деле, стоит ещё в main отдельно очищать полученную строку, т.к. она создана оператором new. Обходного пути придумать не могу.
Advertisement
Add Comment
Please, Sign In to add comment