微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

相同类的C ++实例

如何解决相同类的C ++实例

我想知道在C ++中是否可以像在Java中一样做同样的事情。 意思是这样的:

public class A {
  private A a1;
  private A a2;
  
  A getA1(){
   return a1;
  }

  A getA2(){
   return a2;
  }

  void setA1(A a1){
   this.a1 = a1;
  }

  void setA2(A a2){
   this.a2 = a2;
  }
}

现在,我需要使用C ++的相同内容解决方法

解决方法

是的,它在C ++中是可行的。但是语法会有所不同:

  1. this->而不是this.

  2. private: / public:,而不是每个成员private / public

  3. 记住在课程结束时有;

  4. A*作为成员(或std::uniqe_ptr<A>std::shared_ptr<A>std::weak_ptr<A>的成员。


项目1-3仅是语法。第4项是Java和C ++之间的本质区别:

  • 在Java中,对象变量是对对象的引用,而在C ++中,对象变量是。这就是为什么您不能在C ++中持有自己的直接成员的原因,因为对象的大小将是无限的 (A的实际值为A,实际的值为A A,...递归)。

    在Java中,当A持有A时,它仅持有对另一个A 的引用(是的,您仍然可以递归访问所引用的A,但这并不属于您的大小,您只需保存对其的引用,该引用就会存储在内存中的其他位置。大小的增加只是引用的大小。

    您可以在C ++中使用引用变量指针实现类似的语义,方法是添加&作为引用,或*作为指针:

    A& a2 = a1; // a2 is a reference to A,assigned with a reference to a1
                // note that a1 above is assumed to be also of type A&
    
    A* a2 = a1; // a2 is a pointer to A,assigned with the address stored in a1
                // note that a1 above is assumed to be also of type A*
    
  • Java垃圾收集器回收未使用的内存,而在C ++中,程序员需要处理这些内存,可能需要使用智能指针之类的C ++工具。

  • Java垃圾收集器通过Trace by Reachability回收未使用的内存,C ++智能指针基于作用域生存期。此外,C ++ shared_ptr基于reference counting的优点,但受参考周期的影响,可能会发生内存泄漏,应通过适当设计代码来避免这种情况。


“抱住自己” 的C ++版本可能看起来像下面的任何一种(或它们的变体),具体取决于确切的需求:

选项1-A是持有,但不拥有 a1和a2

class A {
   A* a1 = nullptr;
   A* a2 = nullptr;

public: 
   A* getA1(){
      return a1;
   }

   A* getA2(){
     return a2;
   }

   void setA1(A* a1){
     this->a1 = a1;
   }

   void setA2(A* a2){
     this->a2 = a2;
   }
};

选项2-A具有拥有 a1和a2作为唯一资源

class A {
   std::unique_ptr<A> a1 = nullptr;
   std::unique_ptr<A> a2 = nullptr;

public: 
   A* getA1(){
      return a1.get();
   }

   A* getA2(){
     return a2.get();
   }

   void setA1(std::unique_ptr<A> a1){
     this->a1 = std::move(a1);
   }

   void setA2(std::unique_ptr<A> a2){
     this->a2 = std::move(a2);
   }
};

选项3-A是持有 a1和a2作为共享资源 *

* 需要确保避免循环所有权泄漏。

class A {
   std::shared_ptr<A> a1 = nullptr;
   std::shared_ptr<A> a2 = nullptr;

public: 
   auto getA1(){
      return a1;
   }

   auto getA2(){
     return a2;
   }

   void setA1(std::shared_ptr<A> a1){
     this->a1 = a1;
   }

   void setA2(std::shared_ptr<A> a2){
     this->a2 = a2;
   }
};

选项4-A正在持有指向a1和a2的弱指针 *

* std::weak_ptr的选项在可能存在循环依赖性的情况下是相关的,a1和a2在其他位置拥有并且可能不存在。

class A {
   std::weak_ptr<A> a1 = nullptr;
   std::weak_ptr<A> a2 = nullptr;

public: 
   std::shared_ptr<A> getA1(){
      return a1.lock();
   }

   std::shared_ptr<A> getA2(){
     return a2.lock();
   }

   void setA1(std::shared_ptr<A> a1){
     this->a1 = a1;
   }

   void setA2(std::shared_ptr<A> a2){
     this->a2 = a2;
   }
};

选项4代码示例:http://coliru.stacked-crooked.com/a/92d6004280fdc147


请注意,不能选择使用A&(对A的引用)作为成员,因为在C ++中,参考变量比天主教婚礼强,它们在变量的整个生命周期中都无法重新分配另一个参考。并且必须在出生时将它们分配给有效的参考。

但是,如果a1a2在对象出生时是已知的,则在对象生命周期内永不改变并保持生命,那么以下选项也是可能的:

选项5-A是持有对a1和a2的引用 *

* 仅当在创建时就可以设置对a1a2的引用,并且在更改期间不改变并且保持活动状态时,此选项才有意义。对象的生存期。

class A {
   A& a1;
   A& a2;

public:
   A(A& a1,A& a2): a1(a1),a2(a2) {}

   A& getA1(){
      return a1;
   }

   A& getA2(){
      return a2;
   }
};

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。