如何解决相同类的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 ++中是可行的。但是语法会有所不同:
-
this->
而不是this.
-
private:
/public:
,而不是每个成员private
/public
-
记住在课程结束时有
;
-
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 ++中,参考变量比天主教婚礼强,它们在变量的整个生命周期中都无法重新分配另一个参考。并且必须在出生时将它们分配给有效的参考。
但是,如果a1
和a2
在对象出生时是已知的,则在对象生命周期内永不改变并保持生命,那么以下选项也是可能的:
选项5-A是持有对a1和a2的引用 *
* 仅当在创建时就可以设置对a1
和a2
的引用,并且在更改期间不改变并且保持活动状态时,此选项才有意义。对象的生存期。
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 举报,一经查实,本站将立刻删除。