2016-02-05 129 views
0

所以我想要做的就是存储:对象B和对象B对象的引用没有指针

  • 对象B在对象A和对象B的对象A的
  • 参考

虽然不使用指针。

使用指针和引用我试图避免的唯一区别是访问语法。我不想写“ - >”每次我在对象B.访问对象的时间

我认为可以工作,但会引发分割故障代码:

#ifndef A_H 
#define A_H 

class B; 
class A{ 
    B b; 
public: 
    A(); 
}; 
#endif 

了Bh

#ifndef B_H 
#define B_H 

class A; 
class B{ 
    A& a; 
public: 
    B(A &_a); 
}; 
#endif 

A.cpp

#include "A.h" 
#include "B.h" 

A::A():b(B(*this)){} 

B.cpp

#include "B.h" 
#include "A.h" 

B::B(B &_b):a(_b){}  

我还以为是造成分段错误使用“这”在初始化列表(uninititialized实例)的关键字,但我读过,只要我不访问它的第一件事一切都应该没问题。我的构造函数是空的,所以我不会发生什么错误。

是否可以做到这一点类似于我在做什么?如果没有,那么为什么,有什么可以让我不写' - >'?

编辑: 的确有,因为它只是写成伪代码只是让任何人都没有浪费时间,这里不再粘贴不必要的代码一些编译错误。编写伪代码当然编译完成。 But goo.gl/DHlM6X

但现在它运行没有seg故障。我想我的项目中有一些我做的不同。我将不得不测试一下为什么它在项目中不起作用,我会发布什么问题,以便问题可以有真正的答案。

+0

此代码编译? – NathanOliver

+0

如果我拼写正确,那么是的,在archblock下的codeblocks C++ 11中。 – Antua

+1

有趣。 AFAIK A.h不应该编译,因为您有一个常规变量为不完整类型。 – NathanOliver

回答

1

起初,在这里使用引用而不是乱七八糟的指针似乎是个不错的主意,但是你并没有帮助你自己。为什么?引用意味着链接到一个对象,您可以确定链接对象的寿命长于引用。

所以,你的代码

class B{ 
    A& a; 
}; 

基本规定:“对于B类型的每一个对象有A类型的已知,不可改变对象B类型创建的对象之前存在,并仍将住在B -object被破坏的时间“。

同时你的代码

class A{ 
    B b; 
}; 

指出:“A类型的每个对象由B类型的对象的”,这主要是告诉编译器为A类型的对象分配内存(包括B b的空间),然后在该内存中的正确位置构造一个类型为B的对象,然后构造一个类型为A的对象。但在本例中A被乙之后建造之前销毁B.

两个语句相互排斥。

因此,无论您切换到指针(其中国家“的对象知道X类型的关于另一个对象”,可以是nullptr),或者你可以考虑做这样的事情:

class Combined{ 
    A a; 
    B b; 
} 

,然后添加功能需要了解Combined类中的两个对象。

在标准我发现下面的关于您的问题,为什么它不应该在所有的工作:

9.3.2 this指针[class.this]
在的身体非静态(9.3)成员函数,关键字 是一个prvalue表达式,其值是调用该函数的对象的地址。在类别X的成员函数 中的这种类型是X *。如果成员函数被声明为const(...)

因此,从我可以说,this只有定义了“在非静态成员函数体内”的行为。一些编译器允许this,typeid(this)sizeof(this)也在该类的其他部分,但我无法在标准中找到它。

+0

我认为内存分配恰好在构造函数被触发之前发生,因此A在创建B时有内存。直到B结束其初始化,它才引用B,然后A可以完成其初始化写入引用到正确的位置。我的程序保证从头到尾都有两个对象,所以不需要改变引用或存储nullptr。 组合课只会做很多混乱,因为两个班只做不同的事情,但必须互相转达。我宁愿使用指针:/ 仍然你的答案是迄今为止最好的答案。 – Antua

+0

是的,内存分配发生在构造函数被触发之前。但是直到施工结束,它只是空的(或未初始化的)内存。所以顺序应该是这样的:-A的内存被分配--Ab使用指向A的指针构造--A使用任何在你的构造器体内构造的。这意味着在构造A之前使用指向A的指针。这可能适用于某些编译器,但我不会推荐它,因为它不保证可以在所有编译器上工作(至少从我读过的标准中)。 – Anedar