Un par de pensamientos sobre captadores y definidores en C ++

Este artículo trata sobre captadores y definidores en C ++. Pido disculpas, pero no estamos hablando de corrutinas. Por cierto, la segunda parte sobre los grupos de subprocesos aparecerá en un futuro próximo.





TL; DR : los captadores y definidores no son muy adecuados para objetos estructurados.





Introducción

, - , , , . .





, , , - , , , , .





, :





class PersonGettersSetters {
  public:
    std::string getLastName() const { return m_lastName; }
    std::string getFirstName() const { return m_firstName; }
    int getAge() const {return m_age; }
    
    void setLastName(std::string lastName) { m_lastName = std::move(lastName); }
    void setFirstName(std::string firstName) { m_firstName = std::move(firstName); }
    void setAge(int age) {m_age = age; }
  private:
    int m_age = 26;
    std::string m_firstName = "Antoine";
    std::string m_lastName = "MORRIER";    
};
      
      



.





struct Person {
    int age = 26;
    std::string firstName = "Antoine";
    std::string lastName = "MORRIER";
};
      
      



. , , .





. Person (firstName



), (lastName



) (age



). , , .





std::string getPresentation(const PersonGettersSetters &person) {
  return "Hello, my name is " + person.getFirstName() + " " + person.getLastName() +
  " and I am " + std::to_string(person.getAge());
}

std::string getPresentation(const Person &person) {
  return "Hello, my name is " + person.firstName + " " + person.lastName + " and I am " + std::to_string(person.age);
}
      
      



30% , . ? - . , . person.getFirstName()



; person.firstName



.





, noop.





, . ​​ , . :





class PersonGettersSetters {
  public:
    const std::string &getLastName() const { return m_lastName; }
    const std::string &getFirstName() const { return m_firstName; }
    int getAge() const {return m_age; }
    
    void setLastName(std::string lastName) { m_lastName = std::move(lastName); }
    void setFirstName(std::string firstName) { m_firstName = std::move(firstName); }
    void setAge(int age) {m_age = age; }
  private:
    int m_age = 26;
    std::string m_firstName = "Antoine";
    std::string m_lastName = "MORRIER";    
};

      
      



, , , ? , .





PersonGettersSetters make() {
    return {};   
}

int main() {
    auto &x = make().getLastName();
     
    std::cout << x << std::endl;
    
    for(auto x : make().getLastName()) {
        std::cout << x << ",";   
    }
}
      
      



, . ? , make().getLastName()



?





  1. Person.





  2. .





  3. Person.





! ( ) - , -, .





, ref-qualified



.





class PersonGettersSetters {
  public:
    const std::string &getLastName() const & { return m_lastName; }
    const std::string &getFirstName() const & { return m_firstName; }
    
    std::string getLastName() && { return std::move(m_lastName); }
    std::string getFirstName() && { return std::move(m_firstName); }
    
    int getAge() const {return m_age; }
    
    void setLastName(std::string lastName) { m_lastName = std::move(lastName); }
    void setFirstName(std::string firstName) { m_firstName = std::move(firstName); }
    void setAge(int age) {m_age = age; }
    
  private:
    int m_age = 26;
    std::string m_firstName = "Antoine";
    std::string m_lastName = "MORRIER";    
};
      
      



, . . lvalue



rvalue



( xvalue



, prvalue



).





. , , lvalue



, , rvalue



. , , , . , move. . . A D, . .





?

- const. . move- .





, . , , immutable



<T>. :





  1. Constructible







  2. immutable



    , assignable







  3. copy constructible



    move constructible







  4. const T



    &, lvalue







  5. T



    , rvalue







  6. , , *



    ->



    .





  7. .





:





#define FWD(x) ::std::forward<decltype(x)>(x)

template <typename T>
struct AsPointer {
    using underlying_type = T;
    AsPointer(T &&v) noexcept : v{std::move(v)} {}
    T &operator*() noexcept { return v; }
    T *operator->() noexcept { return std::addressof(v); }
    T v;
};

template <typename T>
struct AsPointer<T &> {
    using underlying_type = T &;
    AsPointer(T &v) noexcept : v{std::addressof(v)} {}
    T &operator*() noexcept { return *v; }
    T *operator->() noexcept { return v; }
    T *v;
};

template<typename T>
class immutable_t {
  public:
    template <typename _T>
    immutable_t(_T &&t) noexcept : m_object{FWD(t)} {}

    template <typename _T>
    immutable_t &operator=(_T &&) = delete;

    operator const T &() const &noexcept { return m_object; }
    const T &operator*() const &noexcept { return m_object; }
    AsPointer<const T &> operator->() const &noexcept { return m_object; }

    operator T() &&noexcept { return std::move(m_object); }
    T operator*() &&noexcept { return std::move(m_object); }
    AsPointer<T> operator->() &&noexcept { return std::move(m_object); }

    T *operator&() &&noexcept = delete;
    const T *operator&() const &noexcept { return std::addressof(m_object); }

    friend auto operator==(const immutable_t &a, const immutable_t &b) noexcept { return *a == *b; }

    friend auto operator<(const immutable_t &a, const immutable_t &b) noexcept { return *a < *b; }

  private:
    T m_object;
};
      
      



, Person :





struct ImmutablePerson {
    immutable_t<int> age = 26;
    immutable_t<std::string> firstName = "Antoine";
    immutable_t<std::string> lastName = "MORRIER";
};
      
      



, - . , - , , :





  • 3- ( 4-): const lvalue



    , rvalue



    , const rvalue



    , , lvalue



    ( , )





  • 1 ( 2, ).





, .





, , . - . , - .





: , , / . , , .





PS: , , . 2 0. , , , .





? ? ?






"C++ Developer. Basic". - «HTTPS ++. ». http- « ». , , - ++ .








All Articles